今年1月に掲題の脆弱性勧告があり、複数のお客様より「Cloudflareはこの脆弱性に該当しますか?」というお問い合わせがありました。
おそらく全てのCDNサービスが該当するのではと思われます。しかし、元の原因はオリジンサーバにあります。
この脆弱性が利用されるのは、お客様のオリジンサーバが特定のふるまいを行う場合のみです。
一部のサーバでは、ユーザからのリクエストに含まれるHTTPヘッダーの一部を抜き出して、それをコンテンツの一部に含めるようなものがあります。
【例】
リクエスト電文
GET /example.html HTTP/1.1
Host: blog.example.com
X-Forwarded-Host: example.bloghost.com
レスポンス電文
HTTP/1.1 200 OK
Cache-Control: public, max-age=604800
Content-Length:
<html>
<img src=https://example.bloghost.com/img/share.jpg”>
朱書き部が、何の処理も施されずにサーバから返されるため、攻撃者が自身のリクエストを細工し、攻撃用のコードを含めることが出来ます。
【例】
リクエスト電文
GET /example.html HTTP/1.1
Host: blog.example.com
X-Forwarded-Host: a.”><script>alert(1)</script>
レスポンス電文
HTTP/1.1 200 OK
Cache-Control: public, max-age=604800
Content-Length:
<html>
<img src=https://a. ”><script>alert(1)</script>
このようにレスポンスのBODYに任意のJavaScriptを含めることが出来ます。 これだけだと、攻撃者が自分自身を攻撃しているかのように見えますが、ここにCDNが加わると、攻撃コードを含んだコンテンツがCDN上にキャッシュされ、他のユーザがそのキャッシュコンテンツを取得してしまうということが発生し得る状態になります。 サーバでなく、他のサイト利用者が攻撃されてしまうタイプの攻撃手法です。
CDNには、何をもって同一のリソースと見なし、キャッシュするのかの設定があります。
リソースのURIが同一でも、クエリー部(URIの後ろの?以降の部分)や一部のHTTPヘッダーの内容が異なれば、別のリソースと見なし、別々にキャッシュします。
例えば、下記などです。
この「何をもって同一のものと見なすか」をCloudflareではキャッシュキーと言います。
HTTPキャッシュポイズニングの攻撃が成立するのは、オリジンサーバの仕様がリクエストの一部をそのまま返すような仕様であり、尚且つCDNのキャッシュキーの条件に当てはまってしまい攻撃者の仕込んだ攻撃用のコードを含んだコンテンツをキャッシュしてしまった場合ということになります。
考えられる回避策は複数あります。HTTPヘッダーにスクリプトが含まれる場合は、WAFでブロックすることも考えられます。
しかし、スクリプトでなく、悪意あるサイトへのURLなどの場合はWAFのチェックでは防ぐことが出来ません。
キャッシュキーの条件を見直すことも有効です。また、特定のURLにおいてキャッシュを無効化することも出来ます。
脆弱性勧告の記事のタイトルが「複数の CDN サービスプロバイダに HTTP キャッシュポイズニングの影響を受ける問題」となっているため誤解をされるケースがあるのですが、上記の説明の通り、CDN単体で問題が起こるようなものではありません。
どのような対策をするかは、サーバの仕様を確認した上で考える必要があります。
執筆者:角田 貴寛
三井情報株式会社
ソリューション技術本部 次世代基盤第二技術部 第一技術室
CISSP、CEH
現在、セキュリティ関連調査研究・教育業務に従事