跳转至

Web 缓存欺骗 (Web Cache Deception)

Web 缓存欺骗 (WCD) 是一种安全漏洞,当 Web 服务器或缓存代理错误地理解了客户端对 Web 资源的请求,并随后在缓存该资源后,向其他请求者提供了一个不同的资源(通常是更敏感或私密的资源)时,就会发生这种漏洞。

摘要 (Summary)

工具 (Tools)

方法论 (Methodology)

Web 缓存欺骗示例:

想象一下,攻击者诱导一个已登录的受害者访问 http://www.example.com/home.php/non-existent.css

  1. 受害者的浏览器请求资源 http://www.example.com/home.php/non-existent.css
  2. 在缓存服务器中搜索请求的资源,但未找到(资源不在缓存中)。
  3. 请求随后被转发到主服务器。
  4. 主服务器返回 http://www.example.com/home.php 的内容,很可能带有指示不要缓存此页面的 HTTP 缓存指令头。
  5. 响应经过缓存服务器。
  6. 缓存服务器识别出该文件具有 CSS 扩展名。
  7. 在缓存目录下,缓存服务器创建一个名为 home.php 的目录,并在其中缓存伪造的“CSS”文件 (non-existent.css)。
  8. 当攻击者请求 http://www.example.com/home.php/non-existent.css 时,请求被发送到缓存服务器,缓存服务器返回缓存的文件,其中包含受害者的敏感 home.php 数据。

WCD 演示图

缓存敏感数据 (Caching Sensitive Data)

示例 1 - PayPal 首页上的 Web 缓存欺骗

  1. 正常浏览,访问首页:https://www.example.com/myaccount/home/
  2. 打开恶意链接:https://www.example.com/myaccount/home/malicious.css
  3. 页面显示为 /home 的内容,并且缓存服务器正在保存该页面。
  4. 在无痕窗口中打开之前的 URL:https://www.example.com/myaccount/home/malicious.css
  5. 缓存的内容被显示出来。

Omer Gil 的攻击视频 - PayPal 首页 Web 缓存欺骗攻击演示 DEMO

示例 2 - OpenAI 上的 Web 缓存欺骗

  1. 攻击者针对 /api/auth/session 端点构造了一个专门的 .css 路径。
  2. 攻击者分发该链接。
  3. 受害者访问该合法链接。
  4. 响应被缓存。
  5. 攻击者窃取 JWT 凭据。

缓存自定义 JavaScript (Caching Custom JavaScript)

  1. 寻找用于缓存污染的非键值输入 (Un-keyed input):

    User-Agent
    Cookie
    响应头X-Forwarded-Host
    响应头X-Host
    响应头X-Forwarded-Server
    响应头X-Forwarded-Scheme (响应头也可与 X-Forwarded-Host 组合使用)
    响应头X-Original-URL (针对 Symfony)
    响应头X-Rewrite-URL (针对 Symfony)
    
  2. 缓存污染攻击 - 以 X-Forwarded-Host 非键值输入为例(请记得使用缓存清除参数以避免污染网站主页):

    GET /test?buster=123 HTTP/1.1
    Host: target.com
    X-Forwarded-Host: test"><script>alert(1)</script>
    
    HTTP/1.1 200 OK
    Cache-Control: public, no-cache
    [..]
    <meta property="og:image" content="https://test"><script>alert(1)</script>">
    

技巧 (Tricks)

以下 URL 格式是检查“缓存”功能的良好起点:

  • https://example.com/app/conversation/.js?test
  • https://example.com/app/conversation/;.js
  • https://example.com/home.php/non-existent.css

检测 Web 缓存欺骗 (Detecting Web Cache Deception)

  1. 检测分隔符差异:/路径/<动态资源>;<静态资源>
  2. 例如:/settings/profile;script.js
  3. 如果原始服务器使用 ; 作为分隔符,但缓存服务器不使用。
  4. 缓存服务器将路径解析为:/settings/profile;script.js
  5. 原始服务器将路径解析为:/settings/profile
  6. 更多分隔符字符请参考:Web 缓存欺骗实验分隔符列表
  7. 检测归一化 (Normalization):/wcd/..%2fprofile
  8. 如果原始服务器解析了路径遍历序列,但缓存服务器没有。
  9. 缓存服务器将路径解析为:/wcd/..%2fprofile
  10. 原始服务器将路径解析为:/profile

CloudFlare 缓存机制 (CloudFlare Caching)

CloudFlare 在 Cache-Control 头设置为 publicmax-age 大于 0 时缓存资源。

在 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 PDF SVGZ WOFF2 TAR
CLASS EXE JS PICT SWF XLS XLSX

例外与绕过:

  • 如果返回的 Content-Typeapplication/octet-stream,则扩展名无关紧要,因为这通常是指示浏览器保存资源而非显示的信号。
  • Cloudflare 允许将 .jpg 作为 image/webp 提供,或者将 .gif 作为 video/webm 提供,以及其他一些认为不太可能成为攻击的情况。
  • 使用 .avif 扩展名绕过缓存欺骗防御 - 已修复

实验环境 (Labs)

参考资料 (References)