Loofah の URI 安全性チェックを Rails::HTML::Sanitizer に委譲

rails/rails-html-sanitizer

Rails フレームワークが Loofah への直接依存なしに URI の安全性を検証できるようになりました。Rails::HTML::Sanitizer.allowed_uri? メソッドの追加により、Rails 側で URI プロトコルの安全性チェックを統一的に実行できます。

背景

Rails フレームワーク内で URI の安全性を検証する際、これまでは Loofah への直接依存が必要でした。Loofah::HTML5::Scrub.allowed_uri? を呼び出すには、Rails 側のコードに Loofah への参照を記述する必要があり、依存関係の境界が曖昧になっていました。#214 は、この依存関係を rails-html-sanitizer 層で吸収する変更です。

Rails のサニタイザー機能は既に Loofah に依存しているため、URI 検証機能も同じ抽象化レイヤーで提供することで、Rails フレームワーク側のコードをシンプルに保てます。

技術的な変更

lib/rails/html/sanitizer.rballowed_uri? クラスメソッドが追加され、Loofah の同名メソッドに処理を委譲します。

def allowed_uri?(uri_string)
  Loofah::HTML5::Scrub.allowed_uri?(uri_string)
end

このメソッドは、https://http://mailto: などの安全なプロトコルには true を返し、javascript: などの危険なプロトコルには false を返します。相対 URI(/relative/path)も安全として扱われます。

def test_allowed_uri_returns_true_for_allowed_protocols
  assert(Rails::HTML::Sanitizer.allowed_uri?("https://example.com"))
  assert(Rails::HTML::Sanitizer.allowed_uri?("http://example.com"))
  assert(Rails::HTML::Sanitizer.allowed_uri?("mailto:user@example.com"))
end

def test_allowed_uri_returns_false_for_disallowed_protocols
  refute(Rails::HTML::Sanitizer.allowed_uri?("javascript:alert(1)"))
end

Loofah の最小依存バージョンが ~> 2.21 から ~> 2.25 に引き上げられました。これは Loofah::HTML5::Scrub.allowed_uri? が Loofah 2.25 で公開 API として追加されたためです。

- spec.add_dependency "loofah", "~> 2.21"
+ spec.add_dependency "loofah", "~> 2.25"

設計判断

委譲パターン による薄いラッパーが採用されました。

PR の実装は、Loofah のメソッドをそのまま呼び出すだけの単純な委譲です。独自のロジックを追加せず、プロトコルの安全性判定は Loofah に完全に任せる設計です。これにより、URI 検証ロジックの重複を避けつつ、Rails フレームワーク側には安定した API を提供できます。

Loofah のバージョン要件を 2.25 以上に引き上げることで、allowed_uri? が公開 API として利用可能であることを保証しています。この判断により、内部実装への依存を避け、Loofah 側の変更に対する耐性を高めています。

本 PR は、既存の依存関係を活用しながら Rails フレームワークに統一的な URI 検証手段を提供する変更です。委譲パターンによる薄い抽象化により、Loofah への直接依存を隠蔽し、Rails 側のコードの保守性を向上させています。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細・設計判断(各論)→まとめ(結論)の3部構成が明確に適用されており、読者が変更の全体像と詳細をスムーズに理解できる構成になっています。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```ruby:filepath)およびGitHubのPR番号リンク([#214](URL))が、ガイドラインに沿って正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

「委譲パターン」「抽象化レイヤー」といった専門用語を適切に用い、Railsフレームワークの内部構造に関心のあるエンジニア向けの内容として、過不足なく書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各段落がトピックセンテンスで始まり、1段落1トピックの原則が守られています。これにより、見出しと各段落の冒頭を読むだけで記事の骨子を把握できる、高い可読性を実現しています。

Diff内容との照合 ⚠ WARNING

コードブロックとDiff内容の一致

主要なコード変更は正確に引用されていますが、`test/rails_api_test.rb` の引用において、相対URIをテストする `test_allowed_uri_returns_true_for_relative_uris` のケースが省略されています。ただし、本文中でその内容に言及があるため、技術的な理解を大きく妨げるものではありません。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「委譲パターン」「公開API」などの技術用語が、PRの文脈に沿って正確かつ効果的に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

Loofahの依存バージョンを引き上げた理由が「公開APIとして追加されたため」であることなど、変更の背景にある技術的な因果関係が、PR情報に基づいて正確に説明されています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(メソッド追加、依存関係の変更、設計意図など)は、PRのDescriptionやDiff内のコードで裏付けられており、ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#214)、Loofahのバージョン番号(~> 2.25)など、記事に含まれる数値や固有名詞はすべて正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「Loofah の URI 安全性チェックを Rails::HTML::Sanitizer に委譲」は、PRの主題を的確に要約しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事の内容は提供されたPR情報に限定されており、サポート状況やリリース予定など、PR外の知識に基づく不確かな情報の追加はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「〜できるようになりました」「〜追加され」といった完了形の表現が使われており、完了した変更であるというPRの時制と一致しています。