午前I問題
WebサーバやCDNにおけるキャッシュ機構に関する記述として、適切なものはどれか。
ア)キャッシュは、一度取得したレスポンスを保存しておき、同一と判定されたリクエストに対して再度オリジンサーバへ問い合わせずに保存済みのレスポンスを返す仕組みであり、どのリクエスト要素(URL・特定ヘッダ等)を「同一」の判定に使うかは「キャッシュキー」の設計によって決まる。
イ)キャッシュは常にリクエストの全ヘッダ・全パラメータを漏れなくキャッシュキーに含めるため、キャッシュキーに含まれないパラメータの違いによってレスポンス内容が変わることはあり得ない。
ウ)キャッシュされたレスポンスは特定の1ユーザにのみ配信される仕組みであり、他の利用者に共有されることはない。
エ)CDNのキャッシュ機構はオリジンサーバのアクセス制御設定を自動的に継承するため、オリジン側で認可されていないリクエストがキャッシュ経由で配信されることはない。
午前I の解答・解説を見る
正解: ア
解説:
- ア)正解。キャッシュは「同一のリクエストには同一のレスポンスを返す」という前提で動作し、その「同一」を判定する基準が「キャッシュキー」である。通常はURLパスや一部のクエリパラメータ・ヘッダのみがキーに含まれ、それ以外(Unkeyed Input)は判定に使われない。
- イ)不正解。実際には多くのCDN・プロキシは特定のパラメータやヘッダのみをキャッシュキーに含める設計になっており、キー化されていない要素の違いによって実際のレスポンス内容が変わっても、同一キャッシュとして扱われてしまうことがある(これがキャッシュポイズニングの技術的原因)。
- ウ)不正解。共有キャッシュ(Shared Cache)は複数の利用者間で共有されるのが一般的であり、これが汚染時の被害拡大につながる。
- エ)不正解。CDNはオリジンのアクセス制御ロジックを自動的に理解・継承するわけではなく、設定不備によりキャッシュ経由で認可外のコンテンツが配信される事故(キャッシュ欺瞞等)が現実に起こり得る。
午前II問題
Webキャッシュポイズニングと「Webキャッシュ欺瞞(Web Cache Deception)」の違いに関する記述のうち、最も適切なものはどれか。
ア)Webキャッシュポイズニングは、キャッシュキーに含まれない入力(Unkeyed Input、例:X-Forwarded-Host ヘッダ)を使って悪意あるレスポンスをオリジンに生成させ、それを正規URLのキャッシュとして汚染・保存させる攻撃であり、Webキャッシュ欺瞞は、動的でキャッシュされるべきでない個人情報を含むページを、URLの末尾に静的リソースを装う拡張子等を付与することで誤ってキャッシュさせ、第三者がそのキャッシュを取得する攻撃である。
イ)Webキャッシュポイズニングと Webキャッシュ欺瞞は全く同じ攻撃を指す別名同士であり、技術的な違いは存在しない。
ウ)Webキャッシュ欺瞞は、攻撃者自身のブラウザキャッシュ(ローカルキャッシュ)を汚染する攻撃であり、他の利用者には一切影響しない。
エ)Webキャッシュポイズニングは、TLS証明書のキャッシュを汚染することでMITM攻撃を成立させる手法である。
午前II の解答・解説を見る
正解: ア
解説:
- ア)正解。両者は原因も影響方向も異なる別の攻撃である。キャッシュポイズニングは「汚染されたレスポンスをキャッシュに書き込ませ、以降の正規利用者にその汚染済みレスポンスが配信される」攻撃(例:
X-Forwarded-Hostを使ったキャッシュ済みXSSペイロードの注入)。キャッシュ欺瞞は逆に「本来キャッシュされるべきでない個人情報付きの動的ページを、攻撃者が誘導したURL(例:/account/profile/nonexistent.js)経由でキャッシュに書き込ませ、その内容を攻撃者自身が読み出す」攻撃である。 - イ)不正解。攻撃の方向性(他者への配信か、自分による窃取か)と原因が異なる別の攻撃である。
- ウ)不正解。Webキャッシュ欺瞞は共有キャッシュ(CDN等)を悪用し他の利用者の機密情報を窃取する攻撃であり、攻撃者自身のローカルキャッシュの話ではない。
- エ)不正解。TLS証明書のキャッシュとは無関係であり、HTTPレスポンスのキャッシュ機構を対象とする攻撃である。
午後問題
I社のWebサイトはCDNによる共有キャッシュを導入している。CDNの設定では、URLパスのみをキャッシュキーとし、クエリパラメータやほとんどのリクエストヘッダはキャッシュキーに含めない(Unkeyed)方式を採用していた。セキュリティ診断で以下の2つの事象が確認された。
事象①
- トップページ(
/)はオリジンサーバがレスポンス内でX-Forwarded-Hostヘッダの値を使って、ページ内の一部リンクのホスト名を動的に生成していた。 - 診断者が
X-Forwarded-Host: evil.example.comを付与してリクエストしたところ、生成されたページ(悪意あるリンクを含む)がCDNのキャッシュに保存され、以降そのURLへアクセスした他の一般利用者にも同じ悪意あるリンクを含むページが配信され続けた。
事象②
- ログイン後にのみ表示される個人情報ページ(
/account/profile、本来Cache-Control: no-storeが付与されキャッシュされない設計)について、診断者が/account/profile/nonexistent.cssという存在しないパスにアクセスしたところ、アプリケーションのルーティング仕様上このパスも/account/profileと同じ内容を返す実装になっており、かつCDNは拡張子.cssを静的リソースと誤認しCache-Controlヘッダの指示を無視してキャッシュしてしまうことが判明した。診断者が別セッションから同一URLにアクセスすると、最初にアクセスした利用者の個人情報が表示された。
設問1
事象①・事象②はそれぞれ何と呼ばれる攻撃に分類されるか、名称を答えよ。また、事象①でキャッシュ汚染が成立した直接的な原因を40字以内で述べよ。
設問1の解答・解説を見る
正解例:
- 事象①:Webキャッシュポイズニング
- 事象②:Webキャッシュ欺瞞(Web Cache Deception)
- 事象①の直接的原因:
X-Forwarded-Hostがキャッシュキーに含まれず、その値に依存するレスポンスがそのままキャッシュされたため(39字)。
解説: 事象①は、レスポンス内容を左右する入力(X-Forwarded-Host)がキャッシュキーに含まれていない「Unkeyed Input」であったために、攻撃者が細工した値に基づくレスポンスが正規URLのキャッシュとして保存され、以降の全利用者に配信されてしまうキャッシュポイズニングの典型例である。事象②は逆に、本来キャッシュされるべきでない個人情報ページが、拡張子偽装によるルーティング・キャッシュ判定の不一致を突かれてキャッシュされてしまうキャッシュ欺瞞の典型例である。
解説・採点基準(計15点):
| 採点項目 | キーワード | 配点 |
|---|---|---|
| 事象①の名称を正しく回答 | Webキャッシュポイズニング | 4点 |
| 事象②の名称を正しく回答 | Webキャッシュ欺瞞、Web Cache Deception | 4点 |
| 事象①原因に「Unkeyed Input(キャッシュキー未包含)」への言及 | キャッシュキーに含まれない、Unkeyed | 7点 |
設問2
事象①・事象②それぞれについて、CDN設定またはアプリケーション実装の観点から有効な対策を1つずつ述べよ。
設問2の解答・解説を見る
正解例:
- 事象①の対策:
X-Forwarded-Hostのようなレスポンス内容に影響する外部入力ヘッダをオリジン側で信頼せず無視する(固定のホスト名を使用する)、またはやむを得ず使用する場合はそのヘッダをキャッシュキーに含めてキャッシュを分離する。 - 事象②の対策:CDNの静的リソース判定をURLの拡張子だけで行わず、オリジンが返す
Content-TypeやCache-Controlヘッダを尊重してキャッシュ可否を判定するよう設定を見直す。あわせてアプリケーション側のルーティングを修正し、存在しないパスへのアクセスに対しては本来のコンテンツを返さず404を返すようにする。
解説: 事象①はキャッシュキー設計(Unkeyed Inputの排除、またはキー化)で対処し、事象②はキャッシュ可否判定をURL拡張子ではなくレスポンスヘッダに基づいて行うことと、ルーティングの厳格化(存在しないパスは404を返す)という2段構えの対策が有効である。いずれも「キャッシュされる条件」と「レスポンス内容が変わる条件」を一致させることが本質的な解決策となる。
解説・採点基準(計15点):
| 採点項目 | キーワード | 配点 |
|---|---|---|
| 事象①対策にヘッダの不信任またはキャッシュキー化への言及 | ヘッダ無視、キャッシュキーに含める | 7点 |
| 事象②対策にCache-Control尊重またはルーティング修正への言及 | Cache-Control尊重、404を返す | 8点(部分点:どちらか一方でも5点) |
重要キーワード
| 用語 | 説明 |
|---|---|
| キャッシュキー | キャッシュが「同一リクエスト」を判定するために用いるリクエスト要素(URL・一部ヘッダ等)の組み合わせ |
| Unkeyed Input | キャッシュキーに含まれないがレスポンス内容に影響を与える入力。キャッシュポイズニングの主要因 |
| Webキャッシュポイズニング | 汚染されたレスポンスを共有キャッシュに書き込ませ、以降の全利用者に配信させる攻撃 |
| Webキャッシュ欺瞞(Web Cache Deception) | 本来キャッシュされるべきでない動的な個人情報ページを、静的リソースを装うURLで誤ってキャッシュさせ第三者が読み出す攻撃 |
| 共有キャッシュ(Shared Cache) | CDNやリバースプロキシ等、複数利用者間でレスポンスを共有するキャッシュ機構 |
| Cache-Control ヘッダ | レスポンスのキャッシュ可否・有効期間等を指示するHTTPヘッダ(例:no-store) |
まとめ
- 午前I視点: キャッシュキーの概念と、キー化されない入力の違いによってレスポンス内容が変わり得るという前提を理解する
- 午前II視点: Webキャッシュポイズニング(他者への汚染配信)とWebキャッシュ欺瞞(自分による窃取)の攻撃方向の違いを明確に区別できるようにする
- 午後視点: Unkeyed Inputの特定、拡張子偽装によるルーティング・キャッシュ不一致の分析、キャッシュキー設計とCache-Control尊重による対策を具体的に説明できるようにする