FlawOpen

flawopen.com/XSS/XSS の種類

反射型・格納型・DOM ベース XSS の違いは?

リファレンスページ
要点

反射型、格納型、DOM ベース XSS は、信頼できないデータがブラウザーの危険なコンテキストへ届く異なる経路を表します。重複することもあります。値の出所、保存の有無、描画するコード、影響を受けるユーザーを確認します。

三つの種類

反射型 XSS — 値がリクエストに含まれる

リクエストの値がコンテキストに応じたエンコードなしで応答に入り、ブラウザーがマークアップやスクリプトとして解釈します。攻撃者が細工したリンクを送る場合もありますが、根本原因はリクエストデータの安全でない描画です。描画時点で出力を修正します。

格納型 XSS — 値が保存される

信頼できない内容が保存され、コメントやプロフィール項目などで他のユーザーへ安全でない形で描画されます。その内容を表示する訪問者が影響を受け、保存値または描画経路を修正するまで続きます。

DOM ベース XSS — クライアントコードがデータを危険な DOM sink に渡す

クライアント側 JavaScript が location.hash、URL パラメーター、サーバー応答データなどの信頼できないソースを読み、innerHTML など危険な DOM sink に渡します。値がサーバーへ届かない場合もありますが、それは必須条件ではありません。DOM ベース XSS はクライアント側の source-to-sink 経路を示し、反射型や格納型の配信と重なることがあります。クライアントのデータフローを修正してください。

修正時に区別が重要な理由

XSS は描画 sink でコンテキストに合った出力エンコードまたは安全な DOM API を使って修正します。反射型・格納型はサーバー描画が関わることが多い一方、クライアント描画でも危険な sink が生じます。DOM ベース XSS ではテキストに innerHTML ではなく textContent を使い、リッチ HTML が必要なら明示的なポリシーを持つ保守されたサニタイザーを使います。サーバー側エンコードだけではクライアントの source-to-sink 経路の確認を代替できません。

これらの分類は重なることがあります

反射型と格納型は、入力がページに届く方法と値が永続化されるかを表します。DOM ベースはクライアント側の source-to-sink 経路を表します。分類は相互排他的ではありません。保存されたプロフィール文をクライアントコードが innerHTML に挿入する場合、格納型かつ DOM ベースの XSS になり得ます。

DOM ベース XSS:危険な sink とテキスト表示

危険 — 信頼できない文字列を HTML として解析
const value = new URLSearchParams(location.search).get("q") ?? "";
target.innerHTML = value;
テキスト表示ならより安全 — 文字列として出力
const value = new URLSearchParams(location.search).get("q") ?? "";
target.textContent = value;

参考資料

関連項目 クロスサイトスクリプティング(XSS、CWE-79)の仕組みと各言語での防ぎ方 — flawopen.com Android addJavascriptInterface のセキュリティリスク Angular の XSS 対策:安全な既定動作とバイパス API MIME sniffing XSS:Content-Type と nosniff CSP と出力エスケープ:両方必要ですか? ReactのdangerouslySetInnerHTMLは安全? DOMPurifyだけでinnerHTMLは安全?