1894 字
9 分钟
WEB缓存欺骗

什么是 Web 缓存欺骗#

Web 缓存欺骗是攻击者利用“缓存服务器(CDN / 反向代理 / 缓存层)与源站对同一请求的处理不一致”来诱使缓存保存本应是用户私有/动态的内容(例如用户账户页面),然后由攻击者请求同一缓存条目以获取受害者的私密数据。它与“缓存投毒”不同:WCD 是让缓存存储敏感响应,缓存投毒是把恶意内容注入缓存。


为什么会发生#

关键在于两个角色如何“解析 URL 与决定是否缓存”:

  • 源站(origin):常见框架(REST、MVC)会把 URL 抽象为路由/参数,可能忽略多余路径片段或文件扩展;

  • 缓存层(CDN / reverse proxy):通常用字符串或规则匹配 URL(例如:路径以 .css、.js、/static/ 结尾即视为静态资源并缓存)。

当源站把某 URL 解析为“动态页面”但缓存把它当作“静态资源”并缓存响应时,就产生了可被利用的差异。攻击者只需引诱已登录用户请求一个特制 URL(例如在受害者看到后发起请求),缓存就可能把包含用户数据的响应存到可公开访问的缓存键中。


常见利用方式#

  1. 静态扩展名规则(Static extension rules) CDN 依据路径后缀(.css、.js、.png 等)来缓存。攻击者把目标动态 URL 后追加静态后缀: 例:https://bank.example.com/account/profile/wcd.css

  2. 静态目录规则(Static directory rules) CDN 配置缓存 /static/ 或 /assets/ 下的内容,攻击者把动态路径放到这些目录下或伪装为该目录。

  3. 文件名规则(robots.txt / favicon.ico 等特殊名) 有些 CDNs 默认会缓存特定文件名(robots.txt、favicon.ico)。将动态内容暴露为这些名称可触发缓存。白皮书中就提到这些规则被滥用的例子。

  4. 路径映射/分隔符/规范化差异


构造攻击的步骤#

  1. 定位敏感动态端点:找出返回用户私密数据的 GET/HEAD/OPTIONS 端点(Session 必须对受害者有效)。

  2. 测试路径/分隔符/扩展名:对目标 URL 追加任意段或静态后缀,观察 origin 是否仍返回相同内容。示例:/account → /account/foo, /account/wcd.css。如果 origin 忽略额外段,则可能可利用。

  3. 触发受害者请求:诱导已登录的受害者点击构造的 URL(社交工程、钓鱼邮件、论坛链接等)。

  4. 检测缓存:自己发起相同 URL 的请求,观察 response header(如 X-Cache: hit、Cache-Control、响应时间是否显著降低)来判断是否由缓存返回。Burp 的 Param Miner/Cache-buster 插件也常用来避免测试时误命中缓存。


如何检测#

  • 看响应头:X-Cache, Via, CF-Cache-Status(Cloudflare),Age 等;X-Cache: hit 或 CF-Cache-Status: HIT 表明缓存命中。

  • 时间差:首次请求慢,后续同一 URL 显著变快 → 可能是缓存命中。

  • 内容-type vs extension 不匹配:如果 URL 以 .css 结尾但 Content-Type: text/html,要警惕。Cloudflare 的 Cache Deception Armor 就基于这点做防护。 The Cloudflare Blog+1

  • 参数化 cache-buster:测试时使用独一无二的 query(?cb=UNIQUE)来确保你在做“新请求”而不是读已存在缓存。PortSwigger 建议使用 Param Miner/自动 cachebuster。

快速检测/判定步骤#

  1. 访问目标动态页面(带会话 cookie)并记下响应头(是否含 Cache-Control、Set-Cookie、Content-Type)。

  2. 访问“伪静态”变体(如追加 .css、.js、或放到 /static/ 下):/account/profile.css。看 origin 是否仍返回 200 且内容与原页面类似。

  3. 读取同一“伪静态” URL 的未登录版本,观察是否能获得相同内容。

  4. 优先查看这些响应头:X-Cache, CF-Cache-Status, Age, Cache-Control, Via, Content-Type。Content-Type: text/html 而 URL 看起来像静态资源是高风险指示器。

  5. 用独一无二的 query string 做对照(cache-buster):/account/profile.css?cb=UNIQUE123 保证是否写入新缓存条目再测试。


利用示例#

  1. 目标(受害者登录): https://example.com/profile 返回用户资料(动态 HTML)。

  2. 测试:GET /profile/wcd.css → 源站仍返回相同 HTML(没有 404/302)。

  3. 诱导受害者访问 https://example.com/profile/wcd.css。

  4. 缓存把这个 HTML 存为 .css 的 key;攻击者随后访问同一 URL(未登录)便能看到缓存中的用户资料。

(真实测试中请使用受控实验环境与授权靶场,如 PortSwigger Labs,切勿在未授权的站点执行攻击。)


风险与影响#

  • 信息泄露:用户个人资料、会话令牌、邮箱、甚至敏感业务数据被公开缓存。

  • 帐户接管 / 横向渗透:泄露的认证凭据或个人信息可被用于进一步利用。

  • 品牌/法律风险:敏感数据泄露可能导致合规与隐私问题。 这些风险使得 WCD 在有会话数据的站点(银行、电子商务、SaaS)里尤其严重。


防御#

多层次防御:在 origin(应用)层、缓存配置层和 CDN 层分别做控制。

应用/源站层#

  1. 不要在 GET 响应中返回私密数据(或对返回进行更严格的认证检查)。

  2. 对动态页面设置合适缓存头:Cache-Control: private, no-store, no-cache, must-revalidate(根据需要选择)。例(nginx):

location /account {
add_header Cache-Control "private, no-store, no-cache, must-revalidate";
}
  1. 确保对路径参数/多余片段进行显式校验:若 URL 不应含额外扩展/段,则返回 404/302 而非返回用户页面。

  2. Content-Type 验证:确保对于请求带某些静态后缀时 Origin 返回的 Content-Type 与文件类型一致(若不一致,返回 404 或 400)。这能阻止 CDN 仅凭扩展缓存 HTML。

缓存 / CDN 配置层#

  1. 基于响应的 Content-Type 决定是否缓存(而不仅凭 URL 扩展)。Cloudflare 的“Cache Deception Armor”即是一例,它验证扩展与 Content-Type 是否匹配。

  2. 只缓存明确允许的路径/扩展(白名单策略而非黑名单),并尽量避免“自动”缓存所有看起来像静态的路径。

  3. 把敏感路径设为不缓存(surrogate-control 或 set header),尤其是账户、会话、支付等相关路由。

  4. 把缓存键包含更多来源信息(例如 Cookie、Authorization header、Vary header),使缓存更精确并避免把有会话的数据公用。注意性能折中。

监控与检测#

  • 启用缓存访问日志与 cache analytics,检测异常命中或不符合规则的 content-type/extension 不匹配请求。Cloudflare、Akamai 等 CDN 提供相应功能。


常见误区#

  • “只要 origin 返回Cache-Control: private就万无一失”:并非总然——若 CDN 忽略源站头或被误配置,仍可能缓存;应在多个层面做防护。

  • “WCD = cache poisoning”:两者有交叉但根本不同(WCD 是缓存敏感响应,投毒是注入恶意内容)。分清很重要以选择正确对策。


推荐行动#

  1. 审计:列出所有可能返回敏感数据的 GET/HEAD/OPTIONS 端点。

  2. 配置:对这些端点在源站返回 Cache-Control: private, no-store。

  3. CDN/缓存:启用基于 Content-Type 的缓存策略或厂商的“Cache Deception”防护规则(如 Cloudflare 的 Cache Deception Armor)。

  4. 监控:设置 cache-hit 异常告警、content-type vs extension 的不匹配告警。

  5. 测试:在授权环境下用 PortSwigger labs、自动化脚本覆盖常见 exploit patterns(扩展名、路径片段、规范化差异等)。


结语#

Web 缓存欺骗利用的是“解析与缓存规则的不一致”——防护要点是在源站拒绝不规范路径 / 明确标注缓存策略,并在 CDN 层基于 response(如 Content-Type)而非仅 URL 扩展做缓存决策。做好源站、缓存和监控三层联防,既能保住性能优势,也能避免敏感数据被缓存泄露。

WEB缓存欺骗
https://lab404.cn/posts/web-cache-deception/
作者
见山
发布于
2025-11-15
许可协议
CC BY-NC-SA 4.0