テック技報最新号へ →
セキュリティ

画像変換 CDN で CSP が外れる:Cache-Control の引き継ぎと取得元リダイレクトを塞ぐ

Cloudflare の /cdn-cgi/image/ で、SVG サニタイザーの不備、Chromium のキャッシュ処理、取得元制限のリダイレクト回避をつないだ XSS が実証された。画像変換・画像 CDN を使うなら、取得元を狭く、オープンリダイレクトを持たず、元画像の Cache-Control や Content-Type を上書き・転送させない構成にする。

@MalwareBibleJP · 2026-10-31
#xss#csp#cdn#cloudflare#cache#open-redirect#svg

3 つの要素(Searchlight Cyber の報告)

  1. SVG サニタイザーの不備: Cloudflare の svg-hush が使う XML ライブラリー xml で、名前空間宣言の値がエスケープされずに書き戻され、検査後にスクリプトが混入した。xml 1.4 以降で修正済みで、現行の main では再現しないと Cloudflare は説明。
  2. Chromium のキャッシュで CSP が消える: 画像変換エンドポイントは元画像の Cache-Control を引き継ぐ。no-cache="Content-Security-Policy" のようにヘッダー名を指定すると、Chromium はそのヘッダーを除いてディスクキャッシュに保存する。初回表示では CSP が効くが、「戻る」でキャッシュから読ませるとスクリプトが動く。Firefox と Safari にはない Chromium 固有の挙動。
  3. 取得元制限の回避: 既定の「This zone only」でも、取得処理がリダイレクト先を再検査しないため、許可された取得元にオープンリダイレクトがあれば外部の画像を読める。ゾーン内のどこかで Cloudflare Access を有効にしていると、そのログアウト用エンドポイントから cloudflare.com 配下のオープンリダイレクトへつなぐ経路で成立し、www.cloudflare.com 上の XSS まで実証された。

同じ考え方が通る他サービス

  • Netlify Image CDN: 取得元の許可が広すぎると、同じ Cache-Control 指定で CSP と Content-Type をキャッシュから外し、HTML として解釈させられる。
  • S3 の署名付き URL: 公開オブジェクトに第三者が自分の認証情報で署名した URL を作ると、Content-Type の上書きに加えて Cache-Control の上書きで CSP を外せる。クエリー文字列をそのまま渡す独自ドメインやリバースプロキシー経由の配信が対象。

対策

  • 画像変換の取得元は自ゾーン内でも必要なパスに絞る。許可した取得元にオープンリダイレクト(ログイン後・ログアウト後の redirect= など)がないか点検する。
  • 画像配信用のホスト名を、アプリ本体と Cookie を共有しない別オリジンに分ける。XSS が成立しても本体のセッションに届かないようにする。
  • 元画像や上流の応答の Cache-Control・Content-Type・Content-Disposition を、そのまま利用者に返さない。配信側で固定値に上書きする。
  • S3 などをリバースプロキシーや独自ドメインで出すときは、response-cache-control や response-content-type などの上書き用クエリーを通さない(署名付き URL をクエリーごと転送しない)。
  • SVG はできればラスター化して返すか、Content-Type: image/svg+xml でも Content-Disposition: attachment と X-Content-Type-Options: nosniff を付けて直接表示させない。
  • CSP はヘッダーだけでなく、キャッシュ経由で外れる可能性がある前提で、同じオリジンに利用者のアップロード物を置かない設計を優先する。

出典

X の元の投稿を開く