Webキャッシュポイゾニング(英語:Web Cache Poisoning、短縮表記:WCP)は、ウェブキャッシュの振る舞いを悪用し、有害なHTTPレスポンスをキャッシュサーバーに保存させ、正規のユーザーに対してその汚染されたコンテンツを配信させる攻撃手法である。この攻撃は、主にコンテンツデリバリネットワーク(CDN)、リバースプロキシ、アプリケーションアクセラレータを標的とする。CDNを対象としたWebキャッシュポイゾニングを、「CDNキャッシュポイゾニング」という。
概要 Webキャッシュは、応答時間の短縮とバックエンドサーバーの負荷軽減のために用いられる。キャッシュの基本的な動作は、「同じリクエストに対しては同じレスポンスを返す」という原則に基づいている。キャッシュサーバーはリクエストを識別するためにキャッシュキー(通常はURL、Hostヘッダーなど)を生成し、これが一致する場合に保存済みのレスポンスを返す。
攻撃者は、キャッシュキーに含まれないがバックエンドの処理には影響を与える「非キー化入力」を特定する。攻撃者は非キー化入力に、悪意のあるペイロード(スクリプトなど)を含んだリクエストを送信する。これによりキャッシュサーバに、生成された有害なレスポンスがキャッシュされる、以降アクセスする全ての正規ユーザーに対してその有害なレスポンスが配信されることになる。
このポイゾニングは、キャッシュサーバとバックエンドサーバの判断基準のずれを利用している。キャッシュサーバは、キャッシュキーの一致をチェックしているが、バックエンドサーバは、非キー化入力の一致をチェックしている。このずれにより、ポイゾニングが可能になっている。
手法
キャッシュキーと非キー化入力 キャッシュシステムは、HTTPリクエストを処理する際、そのリクエストを一意に特定するための識別子(キャッシュキー)を生成する。一般的に、パス(URI)、ホスト名、HTTPヘッダー、Cookieなどが用いられる。
一方で、User-Agent、Referer、Accept-Language、X-Forwarded-Hostなどのヘッダーや、GETリクエストにおけるボディ部は、デフォルトではキーに含まれず、リクエストの識別に使われない。
攻撃者はまず、手動探索やツールを用いて、キャッシュキーには含まれないものの、バックエンドのアプリケーション処理によってレスポンスの内容に変化を与える非キー化入力を特定する。次に、特定した入力にクロスサイトスクリプティングを行い、スクリプトや不正リダイレクトのURLなどの悪意のあるペイロードを注入し、バックエンドサーバーに有害なレスポンスを生成させる。最後に、対象リソースがキャッシュされていないタイミングや古いキャッシュが期限切れになるタイミングなどを狙い、この有害なレスポンスをキャッシュサーバーに保存させることで、以降アクセスする正規ユーザー全員に対して悪意のあるコンテンツを配信し、攻撃を成立させる。
非キー化入力
X-Forwarded-Host インジェクション - バックエンドがリンク生成にこのヘッダーを使用している場合、攻撃者は自身のドメインを指定してスクリプトタグ(例: `<script src="...">`)を生成させ、XSSを成立させる。 X-Forwarded-ProtoによるDoS - HTTPSサイトに対し、`X-Forwarded-Proto: http`を送信して301リダイレクトを誘発し、これをキャッシュさせることで、正規ユーザーを無限リダイレクトループに陥らせる事例(例:Kahoot!の事例)がある。
Unkeyed Query Parameters - Webマーケティング用のパラメータ(例: `utm_content`)はキーから除外されることが多い。これらがページ内にリフレクションされる場合、XSSの経路となる。 Fat GET - GETリクエストのボディに含まれるパラメータをバックエンドが処理する場合、キャッシュ層がボディを無視する仕様を突き、悪意のあるコンテンツをキャッシュさせる。
Cache-Poisoned Denial of Service (CPDoS) Cache-Poisoned Denial of Service (キャッシュ汚染型サービス拒否攻撃、略称:CPDoS)は、キャッシュをエラーページや無効なコンテンツで上書きし、サービスを停止させる攻撃である。キャッシュサーバーとオリジンサーバーのヘッダーサイズの制限差を利用したHHO (HTTP Header Oversize) や、制御文字を利用したHMC (HTTP Meta Character) などの手法が存在する。主にCDNが標的とされ、かつ大量のトラフィックを必要とせず、広範囲のユーザーに影響を与えることができるのが特徴である。
防御策 防御には、インフラス、CDN、アプリケーションの各層における多層防御が必要である。2024年のACM CCSで発表された研究では、HTTP/2とHTTP/1.1の変換差異や、Rangeリクエストの処理不備を悪用した新たな攻撃ベクトルが特定されている。調査によると、トップドメインの約17%がいまだにWebキャッシュポイゾニングに対して脆弱であるとされる。
検出 Webキャッシュポイゾニングの検出は、キャッシュの挙動が見えにくいブラックボックステストである。自動化ツールとしては、James Kettleが開発者のParam Miner(Burp Suite拡張機能)や、大規模スキャン向けのHCache、DoS攻撃検出に特化したToxicacheなどが利用される。
対策
Nginxでキャッシュキーを生成するディレクティブであるproxy_cache_keyを使用し、キーに含める要素を明示的に、かつ最小限に定義する。 VCL(Varnish Configuration Language)を用いてリクエストヘッダーの正規化を行い、危険なヘッダーを無効化する。
主要なCDNプロバイダーの対策機能を導入し、キャッシュキーの要素の制御、オリジン到達前のヘッダー削除や正規化をする。
アプリケーション層で、コンテンツ生成に使用したヘッダー(例:X-Forwarded-Host)を`Vary`レスポンスヘッダーに指定することで、キャッシュの断片化を促しポイズニングを防ぐ。 Ruby on Railsにおいて、 `config.hosts`設定でホスト名をホワイトリスト化し、ホストヘッダーに起因する脆弱性(特にWebキャッシュポイズニングやHostヘッダーインジェクション)を防ぐ。
その他 Webキャッシュポイゾニングは、Web Cache Deception(WCD)は混同されやすいが、その目的は異なる。Webキャッシュポイゾニングは、ポイゾニングを行うことで、不特定多数のユーザーに対し、改ざんされたコンテンツや悪意のあるスクリプトを配信する。一方、Web Cache Deception(WCD)は、攻撃対象者を誘導して機密情報を含むページをキャッシュさせ、攻撃者がそれを取得する攻撃である。
脚注
関連項目
エクスプロイト CDN キャッシュ