Web 缓存欺骗 (Web Cache Deception)
Web 缓存欺骗 (WCD) 是一种安全漏洞,当 Web 服务器或缓存代理错误地理解了客户端对 Web 资源的请求,并随后在缓存该资源后,向其他请求者提供了一个不同的资源(通常是更敏感或私密的资源)时,就会发生这种漏洞。
摘要 (Summary)
工具 (Tools)
- PortSwigger/param-miner - 用于检测 Web 缓存污染(Web Cache Poisoning)的 Burp 插件。
方法论 (Methodology)
Web 缓存欺骗示例:
想象一下,攻击者诱导一个已登录的受害者访问 http://www.example.com/home.php/non-existent.css
- 受害者的浏览器请求资源
http://www.example.com/home.php/non-existent.css - 在缓存服务器中搜索请求的资源,但未找到(资源不在缓存中)。
- 请求随后被转发到主服务器。
- 主服务器返回
http://www.example.com/home.php的内容,很可能带有指示不要缓存此页面的 HTTP 缓存指令头。 - 响应经过缓存服务器。
- 缓存服务器识别出该文件具有 CSS 扩展名。
- 在缓存目录下,缓存服务器创建一个名为
home.php的目录,并在其中缓存伪造的“CSS”文件 (non-existent.css)。 - 当攻击者请求
http://www.example.com/home.php/non-existent.css时,请求被发送到缓存服务器,缓存服务器返回缓存的文件,其中包含受害者的敏感home.php数据。

缓存敏感数据 (Caching Sensitive Data)
示例 1 - PayPal 首页上的 Web 缓存欺骗
- 正常浏览,访问首页:
https://www.example.com/myaccount/home/ - 打开恶意链接:
https://www.example.com/myaccount/home/malicious.css - 页面显示为
/home的内容,并且缓存服务器正在保存该页面。 - 在无痕窗口中打开之前的 URL:
https://www.example.com/myaccount/home/malicious.css - 缓存的内容被显示出来。
Omer Gil 的攻击视频 - PayPal 首页 Web 缓存欺骗攻击演示
示例 2 - OpenAI 上的 Web 缓存欺骗
- 攻击者针对
/api/auth/session端点构造了一个专门的.css路径。 - 攻击者分发该链接。
- 受害者访问该合法链接。
- 响应被缓存。
- 攻击者窃取 JWT 凭据。
缓存自定义 JavaScript (Caching Custom JavaScript)
-
寻找用于缓存污染的非键值输入 (Un-keyed input):
-
缓存污染攻击 - 以
X-Forwarded-Host非键值输入为例(请记得使用缓存清除参数以避免污染网站主页):
技巧 (Tricks)
以下 URL 格式是检查“缓存”功能的良好起点:
https://example.com/app/conversation/.js?testhttps://example.com/app/conversation/;.jshttps://example.com/home.php/non-existent.css
检测 Web 缓存欺骗 (Detecting Web Cache Deception)
- 检测分隔符差异:
/路径/<动态资源>;<静态资源> - 例如:
/settings/profile;script.js - 如果原始服务器使用
;作为分隔符,但缓存服务器不使用。 - 缓存服务器将路径解析为:
/settings/profile;script.js - 原始服务器将路径解析为:
/settings/profile - 更多分隔符字符请参考:Web 缓存欺骗实验分隔符列表
- 检测归一化 (Normalization):
/wcd/..%2fprofile - 如果原始服务器解析了路径遍历序列,但缓存服务器没有。
- 缓存服务器将路径解析为:
/wcd/..%2fprofile - 原始服务器将路径解析为:
/profile
CloudFlare 缓存机制 (CloudFlare Caching)
CloudFlare 在 Cache-Control 头设置为 public 且 max-age 大于 0 时缓存资源。
- Cloudflare CDN 默认不缓存 HTML。
- Cloudflare 仅根据文件扩展名而非 MIME 类型进行缓存:cloudflare/默认缓存行为
在 Cloudflare CDN 中,可以实现 缓存欺骗防御 (Cache Deception Armor),该功能默认不开启。
当开启 缓存欺骗防御 后,规则将验证 URL 的扩展名是否与返回的 Content-Type 匹配。
CloudFlare 有一个在其负载均衡器后会被缓存的默认扩展名列表:
| 7Z | CSV | GIF | MIDI | PNG | TIF | ZIP |
| AVI | DOC | GZ | MKV | PPT | TIFF | ZST |
| AVIF | DOCX | ICO | MP3 | PPTX | TTF | CSS |
| APK | DMG | ISO | MP4 | PS | WEBM | FLAC |
| BIN | EJS | JAR | OGG | RAR | WEBP | MID |
| BMP | EOT | JPG | OTF | SVG | WOFF | PLS |
| BZ2 | EPS | JPEG | SVGZ | WOFF2 | TAR | |
| CLASS | EXE | JS | PICT | SWF | XLS | XLSX |
例外与绕过:
- 如果返回的
Content-Type是application/octet-stream,则扩展名无关紧要,因为这通常是指示浏览器保存资源而非显示的信号。 - Cloudflare 允许将
.jpg作为image/webp提供,或者将.gif作为video/webm提供,以及其他一些认为不太可能成为攻击的情况。 - 使用 .avif 扩展名绕过缓存欺骗防御 - 已修复
实验环境 (Labs)
参考资料 (References)
- 缓存欺骗防御 - Cloudflare - 2023年5月20日
- 利用缓存设计缺陷 - PortSwigger - 2020年5月4日
- 利用缓存实现缺陷 - PortSwigger - 2020年5月4日
- 我如何测试 Web 缓存漏洞 + 提示与技巧 - bombon (0xbxmbn) - 2022年7月21日
- OpenAI 账户接管 - Nagli (@naglinagli) - 2023年3月24日
- 实战 Web 缓存污染 - James Kettle (@albinowax) - 2018年8月9日
- Shockwave 发现影响 OpenAI ChatGPT 的 Web 缓存欺骗与账户接管漏洞 - Nagli (@naglinagli) - 2024年7月15日
- Web 缓存欺骗攻击 - Omer Gil - 2017年2月27日
- 导致用户信息泄露的 Web 缓存欺骗攻击 - Kunal Pandey (@kunal94) - 2019年2月25日
- Web 缓存纠缠:缓存污染的新路径 - James Kettle (@albinowax) - 2020年8月5日
- Web 缓存污染 - PortSwigger - 2020年5月4日