Apache mod_cache — Range リクエストによるキャッシュ汚染

リバースプロキシ構成の Apache + mod_cache で、キャッシュが空の URL への初回アクセスが HTTP Range リクエスト(206 Partial Content)だった場合、その断片だけをキャッシュしてしまい、以降その URL の「完全なキャッシュ」として配信してしまう問題。

発生条件

再現(要旨)

初回に Range: bytes=0-3 で先頭 4 バイトだけ取得すると、その hell という断片がキャッシュされ、次の通常アクセスでも断片が「完全版」として返ってしまう。

curl -H 'Range: bytes=0-3' http://.../proxy/hello_world   # → hell(これがキャッシュされる)
curl        http://.../proxy/hello_world                  # → hell(断片が完全版として配信される)

影響

攻撃者が任意 URL のキャッシュを「壊れた断片」で先に作れてしまうため、正規のコンテンツを表示させない サービス不能(DoS) になりうる。CDN のように共有キャッシュを挟む構成では影響が大きい。

補足

本家では 2.2.23/2.3.6 で「206 応答はキャッシュしない」よう修正済み(CVE として処理されたものではなく、挙動変更として入った)。見つけたのは 2013 年末で、翌 2014 年に再現手順つきで gist として公開した。詳しい設定と全手順は当時の gist(gist.github.com/kimoto/6b347dfbaa9f6a87c0c7)に残っている。