Web セキュリティ

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

約 4 分で読めます

XSS (クロスサイトスクリプティング) とは

XSS (Cross-Site Scripting) とは、Web アプリケーションの脆弱性を悪用して、ユーザーのブラウザ上で悪意のある JavaScript を実行させる攻撃手法です。攻撃者が注入したスクリプトは、被害者のブラウザ上で正規のサイトのコンテキストで実行されるため、Cookie の窃取、セッションハイジャック、フィッシングページへのリダイレクト、キー入力の記録など、広範な被害を引き起こします。

OWASP Top 10 では 2021 年版以降、XSS は単独の項目ではなく CWE-79 (Cross-Site Scripting) として Injection カテゴリに含まれています (2021 年版は A03:2021、2025 年版は A05:2025)。OWASP の 2025 年版の集計では Cross-Site Scripting に 3 万件を超える CVE が報告されており、Web アプリケーション開発者が最初に理解すべきセキュリティリスクの 1 つです。

XSS の 3 つの種類

XSS は攻撃の仕組みによって 3 つに分類されます。

反射型 XSS (Reflected XSS)

ユーザーが送信したデータ (URL パラメータ、フォーム入力など) が、サーバーからのレスポンスにそのまま反映される場合に発生します。攻撃者は悪意のあるスクリプトを含む URL を作成し、被害者にクリックさせます。検索結果ページやエラーメッセージで入力値をエスケープせずに表示するケースが典型例です。

格納型 XSS (Stored XSS)

悪意のあるスクリプトがサーバーのデータベースに保存され、他のユーザーがそのデータを閲覧するたびにスクリプトが実行されます。掲示板の投稿、ユーザープロフィール、コメント欄などが攻撃対象になります。反射型と異なり、被害者が特定の URL をクリックする必要がないため、影響範囲が広くなります。

DOM ベース XSS

サーバー側ではなく、クライアント側の JavaScript が DOM (Document Object Model) を操作する際に発生します。document.location、document.URL、innerHTML などを通じて、ユーザー入力が安全でない方法で DOM に挿入されるケースです。攻撃コードがフラグメント識別子 (URL の # 以降) に置かれた場合、その部分はブラウザからサーバーへ送信されないため、サーバー側のアクセスログには痕跡が残りません。

具体的な攻撃シナリオ

XSS 攻撃がどのように実行されるか、具体的なシナリオで理解します。

Cookie 窃取によるセッションハイジャック

攻撃者が掲示板に以下のようなスクリプトを投稿します。他のユーザーがその投稿を閲覧すると、ブラウザに保存されたセッション Cookie が攻撃者のサーバーに送信されます。攻撃者はその Cookie を使って被害者のセッションを乗っ取り、被害者としてログインした状態でサイトを操作できます。

セッション Cookie に HttpOnly 属性が設定されていれば、document.cookie 経由での読み取りは遮断されます。ただし遮断されるのは Cookie の読み出しだけであり、注入されたスクリプトが被害者のブラウザからそのままリクエストを送信して操作を行う攻撃は防げません。

フィッシングフォームの注入

XSS を利用して正規サイト上に偽のログインフォームを表示し、ユーザーの認証情報を窃取します。URL は正規のドメインのままで、通信も正規サイトの証明書で保護された状態に見えるため、アドレスバーの目視確認では偽フォームと判別できません。

防御策と実装のベストプラクティス

XSS 対策は、出力のエスケープを軸に、入力の検証とブラウザの保護機能を組み合わせた多層防御が基本です。

  • 出力エスケープの徹底: HTML、JavaScript、URL、CSS など、出力先のコンテキストに応じた適切なエスケープ処理を行う。HTML コンテキストでは <、>、&、"、' をエンティティに変換する
  • CSP (Content Security Policy) の導入: インラインスクリプトの実行を禁止し、許可されたドメインからのスクリプトのみを実行可能にする。XSS が発生した場合の被害を抑える層として機能するが、設定内容によっては回避経路が残るため、出力エスケープの代わりにはならない
  • Cookie の HttpOnly 属性: セッション Cookie に HttpOnly を設定し、JavaScript からのアクセスを遮断する
  • 入力のバリデーション: ユーザー入力を受け付ける際に、期待される形式 (数値、メールアドレスなど) に合致するか検証する。ただし、入力バリデーションだけでは XSS を完全に防げないため、出力エスケープと併用する
  • テンプレートエンジンの自動エスケープ: React、Vue、Angular などのフレームワークはデフォルトで出力をエスケープする。dangerouslySetInnerHTML (React) や v-html (Vue) の使用は最小限に抑える
  • セキュリティヘッダーの設定: X-Content-Type-Options: nosniff で MIME タイプスニッフィングを防止する

WAF による XSS パターンの検知も有効ですが、WAF はバイパスされる可能性があるため、アプリケーション側の対策を代替するものではありません。

よくある誤解

XSS は見た目を改ざんするだけの軽微な脆弱性
XSS はセッションハイジャック、認証情報の窃取、マルウェアの配布、管理者権限の奪取など、深刻な被害につながる。特に格納型 XSS は、サイトを訪問するすべてのユーザーに影響するため、影響範囲が極めて広い。
入力をバリデーションすれば XSS は防げる
入力バリデーションは防御の一層にすぎない。攻撃者はエンコーディングの変換、Unicode の正規化、コンテキストの切り替えなど多様な手法でバリデーションを回避する。根本的な対策は出力時のコンテキストに応じたエスケープ処理であり、CSP との併用が推奨される。

XSS と CSRF の比較

XSS

被害者のブラウザ上で攻撃者のスクリプトを実行する。サイトがユーザーを信頼していることを悪用する。対策は出力エスケープと CSP。Cookie の窃取やセッションハイジャックが主な被害。

CSRF

被害者のブラウザから正規のリクエストを偽造する。ユーザーがサイトを信頼していることを悪用する。対策はトークン検証と SameSite Cookie。意図しない操作の実行が主な被害。

共有する

関連用語

関連記事