XSSを理解する
同じ文字列でも、文字として表示するかHTMLとして解釈するかで結果が変わります。投稿・検索・ブラウザ内処理を例に、XSSの発生場所と出力先に合う対策を学びます。
この単元で学ぶこと
- 入力が命令として解釈される原因を説明する
- 処理する場所に合う根本対策を選ぶ
- 補助対策の効果と限界を区別する
- 事例から修正と確認の手順を組み立てる
本文解説
ブラウザが解釈する内容 ブラウザはHTMLを構造として読み、JavaScriptを実行します。投稿や検索語を文字として見せたいのに、ページ内の実行可能な内容として解釈されるとXSSにつながります。不正な処理は閲覧者のブラウザ上でサイトの文脈として動き、表示の改変や情報・操作への影響を生じ得ます。SQLインジェクションがDB側の命令を狙う点と区別します。
反射型と蓄積型 検索語が直後の応答へ危険な形で反映されるものが反射型の代表例です。掲示板へ保存した内容を後の閲覧者へ出力するものが蓄積型の代表例です。保存された値だから安全とは限りません。投稿者だけでなく、閲覧者や管理画面を開く担当者が影響を受ける場合があります。
DOM Based XSS サーバーの応答だけでなく、ブラウザ側のJavaScriptも調べます。URLのフラグメントなどから得た値をinnerHTML等へ無加工で渡すと、クライアント側の処理で問題が起こり得ます。フラグメントは通常サーバーへ送られないので、サーバーログだけを見てもその値を把握できない場合があります。反射・蓄積というデータ経路の観点と、DOM側の処理という観点を混同しません。
文字として表示する具体例 HTMLを許可しない通常のdivへ <b>合格</b> を見せたい場合、textContentへその文字列を設定するとタグも含めて文字として表示されます。innerHTMLへ未加工で渡すとHTMLとして解析され、同じ文字の扱いが変わります。サーバーのテンプレートでは、HTML本文に合うエスケープを使い、意図せず生HTML出力へ切り替えないようにします。
出力文脈を確認する HTML本文、引用符で囲む属性、URL、JavaScriptでは解釈規則が異なります。HTML用に処理した値をそのままスクリプトへ埋め込めば安全とはいえません。実行コードへの直接挿入を避け、安全なデータ受渡しやAPIを選びます。リンク先URLでは許可するスキーム等も検証し、属性の構文処理だけで危険なURLの意味を消したと思わないようにします。
HTML装飾を許可するとき 文字だけを表示する場合と、太字や箇条書き等を許可する場合は設計が異なります。後者では保守されているHTMLサニタイザーを使い、許可する要素・属性・URL等を限定します。scriptという文字だけ削除してもイベント属性等の経路が残り得ます。独自の単純な置換でHTMLの解析を再現しようとしません。
CookieとCSPの守備範囲 HttpOnlyはJavaScriptからそのCookieを直接読むことを抑えますが、XSSによる表示の改変や操作等の全影響を防ぎません。CSPも実行元等を制限する補助防御で、内容と適用状況を確認する必要があります。HTTPS、HttpOnly、CSPがあることを理由に、危険な出力を残さないようにします。
経路ごとの修正確認 入力元と表示先を結び付け、検索結果、投稿一覧、詳細、管理画面、ブラウザ内のDOM更新を確認します。認証済み利用者の投稿も無条件に信用せず、新規値と既存保存値の両方を検証します。通常の文章や記号を正しく表示できることと、実行可能な内容として取り込まないことを確認します。自動エスケープの例外指定やURLの扱いも対象です。
図解
重要ポイント
- XSSではブラウザ側の解釈と実行が問題になる。
- 文字表示には安全なAPIや文脈に合うエスケープを使う。
- HTMLを許可する場合は許可範囲を限定してサニタイズする。
間違えやすい点
- 一種類のエスケープを全ての出力文脈へ流用しない。
- HttpOnlyやCSPをXSSの根本対策の代わりにしない。
- 保存済み・社内・認証済みという理由で入力を信用しない。
用語解説
- XSS
- 信頼できない入力を介して、Webページ内で不正なスクリプト等を実行させる攻撃。
- 出力エスケープ
- 出力先で特別な意味を持つ文字を、文字として扱うために適した表現へ変える処理。
- サニタイズ
- 許可する内容の規則に従い、危険な要素や属性等を取り除くなどして安全化する処理。
- DOM
- ブラウザが文書の構造をプログラムから扱うための表現と仕組み。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。