FlawOpen

flawopen.com/クロスサイトスクリプティング

クロスサイトスクリプティング

重要 CWE-79
言語: English Português (Brasil) Español Français Deutsch Русский 简体中文 日本語 हिन्दी 한국어 Bahasa Indonesia

クロスサイトスクリプティングは、あるユーザーの文章をブラウザーが HTML や JavaScript として解析してしまう形でページに入れたとき、その文章がサイト自身の権限で他のユーザーのもとで実行されることで起こります。修正方法はどこでも同じで、値を書き込む場所に合わせて正確にエンコードし、HTML を許す必要があるまれな項目はサニタイズし、両方を Content Security Policy で補強することです。下で言語を選ぶと、正確な API、脆弱なコードと修正後のコード、CI で検出するルールを確認できます。

わかりやすい解説 (ELI5)

新聞は読者からの投書を自分の紙面に載せます。ある読者が、編集部からのお知らせとまったく同じ体裁の投書を送ってきました。「購読者の皆様、更新のためこの番号に電話してカード情報をお伝えください」。新聞と同じ書体で印刷されているので、読者は編集部が書いたものと同じように信じてしまいます。XSS とは、Web サイトが訪問者の文章を自分のページに刷り込み、ブラウザーがそれをサイト自身のコードとして、サイトがあなたのアカウントに持つ権限のまま実行してしまうことです。エスケープとは、すべての投書をはっきり区切られた引用枠の中に印刷し、どの投書も編集部のお知らせになりすませないようにすることです。

主要な概念と専門用語

Cross-site scripting (CWE-79)
Web ページが信頼できないデータをブラウザー向けに無害化せずに含めるため、そのデータ内のマークアップやスクリプトがページのオリジンで解析・実行され、DOM、cookie、API にアクセスできてしまいます。
Reflected, stored and DOM-based XSS
反射型 XSS はリクエストのデータをそのままレスポンスに返し、多くの場合は細工したリンク経由で起こります。格納型 XSS は値を保存してすべての閲覧者に配信します。DOM ベースの XSS はサーバーを通らず、クライアント側の JavaScript が URL やストレージのデータを innerHTML などのシンクにコピーします。
Contextual output encoding
出力の文脈ごとに別のエンコードが必要です。要素のテキストと引用符付き属性には HTML エンティティ、スクリプト内では JavaScript の文字列エスケープ、URL パラメータにはパーセントエンコード、href と src にはスキームの確認を使います。スクリプト内に置く値を HTML エンコードするだけでは不十分です。
Sanitizing vs encoding
エンコードはマークアップを文字として表示します。ユーザーが書式を送る必要がある場合は、許可リスト型のサニタイザー(DOMPurify、bleach の後継である nh3、OWASP Java HTML Sanitizer、HtmlSanitizer、ammonia)に HTML を通し、許可したタグを残してスクリプト、イベントハンドラー、javascript: URL を取り除きます。
Content Security Policy (CSP)
どのスクリプトの実行を許すかをブラウザーに伝えるレスポンスヘッダーです。nonce ベースで 'unsafe-inline' を含まない script-src は、エンコードの不具合が紛れ込んでも注入されたスクリプトの大半を止め、require-trusted-types-for 'script' は DOM のシンクを固めます。

ステップ・バイ・ステップの攻撃フロー

ステップ 1

信頼できない文字列がページに届く

検索語、プロフィールの項目、コメント、URL のフラグメント、API のレスポンスが、サーバーでのページ生成時やブラウザーでの更新時に取り込まれます。

ステップ 2

正しいエンコードなしで書き込まれる

テンプレートのエスケープが無効になっている、値が HTML エスケープではカバーできないスクリプトや URL の文脈に入る、またはクライアントのコードがそれを innerHTML に代入します。無害なテスト値 <img src=x onerror=alert(1)> がそのまま残ります。

ステップ 3

ブラウザーがそれをコードとして解析する

被害者のブラウザーが本物の <img> 要素を作って onerror を発火させるか、クリック時に javascript: のリンクを実行します。

ステップ 4

スクリプトがサイトとして振る舞う

サイトのオリジンで実行されるため、ページを読み、被害者の cookie やトークンでサイトの API を呼び、ユーザーに見える内容を書き換え、本人になりすましてフォームを送信できます。

言語別の XSS 対策ガイド

Python JavaScript Go Java PHP C# Ruby C/C++ Rust Kotlin Swift

エンジニアリング&システム堅牢化チェックリスト

関連記事

反射型・格納型・DOM 型 XSS の解説 エスケープだけで十分か CSP とエスケープの違い DOMPurify だけで十分か Markdown のレンダリングによる XSS