何が起きるか

Webキャッシュポイズニングは、攻撃者のリクエストで作らせた不正な応答を共有キャッシュへ保存させ、他の利用者にも配信させる攻撃です。キャッシュはURLなどをキーに応答を再利用するため、応答を変える入力をキーで区別しないと、攻撃者向けと通常のページが混ざります。

説明用に、アプリがリクエストヘッダーからapp.jsを読むホストを決める構成を考えます。攻撃者が自分のホストをヘッダーへ入れると、アプリは攻撃者のapp.jsを読み込むHTMLを返します。CDNがそのヘッダーをキーにせずURLだけでHTMLを保存すると、同じURLを開いた他の利用者にもそのHTMLを配信します。 この例では、CDNがアプリのCache-Controlによる共有許可に従ってHTMLを一定時間保存する設定だと仮定します。保存可否のルールを満たした応答が、URLをキーに登録されます。

被害者のブラウザが攻撃者のapp.jsをページのスクリプトとして実行し、コードがページ内の個人情報を外部サーバーへ送信できれば、攻撃者が情報を入手できます。キャッシュへ保存されること、保存中に被害者のキーが一致すること、スクリプトの読み込み・実行・外部送信が成立することが条件です。 script要素で読み込む外部のJavaScriptは、ファイルの取得元が別ホストでも、それを組み込んだページのスクリプトとして実行されます。そのため正規サイトのページの要素を読めるのであり、攻撃者のサイトから別サイトの応答を直接読む構成とは異なります。

正常ならどう動くか

CDNなどのキャッシュは、アプリのHTTPレスポンスを保存し、URLなどから作るキャッシュキーが一致するリクエストへ再利用します。保存するのはアプリが返したページやリダイレクトなどで、利用者本人がファイル保存操作をするわけではありません。レスポンスを変える入力はキーで区別するか、そのレスポンスを共有キャッシュへ保存しない必要があります。

不備と攻撃が成立する流れ

説明用の例として、アプリがHTTPリクエストのヘッダーを使って、ページに埋め込むapp.jsのホスト名を決める構成を考えます。攻撃者がそのヘッダーに自分のホスト名を指定すると、アプリは攻撃者のサーバーからapp.jsを読むHTMLを返します。

共有キャッシュがそのヘッダーをキーに含めず、ページのURLだけでレスポンスを保存すると、攻撃者向けのHTMLと通常のHTMLを区別できません。別の利用者が通常のリクエストで同じURLを開くと、キャッシュが保存済みの不正なHTMLを返します。その利用者のブラウザも、HTMLに書かれた攻撃者のapp.jsを取得します。

ここでの不備は、不正なレスポンスが作れることに加え、そのレスポンスを通常のリクエストと同じキーで共有することです。キャッシュへの保存条件を満たし、保存期間中に被害者のリクエストとキーが一致する必要があります。

起こり得る被害と条件

XSSの例では、被害者のブラウザが攻撃者のapp.jsをページのスクリプトとして実行します。そのコードがページ内の個人情報を読み、攻撃者のサーバーへ送信できれば、攻撃者は他人の情報を入手できます。外部スクリプトの読み込み・実行と情報送信が許されることが追加条件です。

誘導の例では、アプリがヘッダーの値からリダイレクト先を作り、そのHTTPレスポンスが共有キャッシュへ保存されます。被害者にも同じ転送先が返ると、正規URLを開いたブラウザが攻撃者のサイトへ移動します。その先の偽ログイン画面へ被害者がパスワードを入力し、フォームが攻撃者のサーバーへ送信すると、攻撃者がその値を取得するおそれがあります。

防ぎ方と、防げる理由

ページやリダイレクトのURL生成には管理された正規ホスト設定を使い、利用者が指定したヘッダーを無条件に採用しません。レスポンス内容を変える入力はキャッシュキーで区別します。利用者別の情報や秘密を含むレスポンスは共有保存の対象から外し、ある利用者向けのレスポンスが他人へ配信されることを防ぎます。

よくある誤解

Cache-Controlは、アプリがHTTPレスポンスへ付け、ブラウザやCDNに保存可否・期間などを伝えるヘッダーです。ただしCDN側に別の保存ルールが設定されている場合もあるため、アプリの指定だけから実際の挙動を判断しません。通常ページに加え、エラーとリダイレクトも実際の保存条件とキーを確認します。

実装の確認点

CDNとアプリの両方で、キーに使う値、応答の保存条件、保存期間を確認します。応答が変わるヘッダーやCookieがキーで区別されるかを、他の利用者へ影響しない専用環境で調べます。

出典・確認範囲

  1. [1] Web Security Academy: WebキャッシュポイズニングPortSwigger / 確認日 2026-10-29