一、什么是 Web Cache Poisoning
Web Cache Poisoning(Web 缓存投毒)是一种攻击者通过操纵缓存服务器,将恶意内容注入缓存,使后续正常用户在访问同一资源时收到被污染响应的攻击技术。该漏洞由安全研究员 James Kettle 于 2018 年在 Black Hat 大会上首次系统性提出,此后迅速成为 Web 安全领域的重要议题。
与传统 Web 攻击不同,缓存投毒的核心在于利用缓存层与应用层之间的解析差异。攻击者并不直接攻击目标用户,而是"毒化"缓存这一中间层,让缓存服务器代替攻击者向大量用户分发恶意内容。
二、漏洞原理深度剖析
2.1 缓存工作机制
Web 缓存通常位于客户端与源服务器之间,其核心逻辑如下:
- 缓存键(Cache Key) :缓存服务器用于标识资源唯一性的字段组合,通常包括 URL 路径、查询字符串、Host 头等。
- 缓存命中判定:当请求到达时,缓存服务器根据缓存键查找是否已有对应响应。若命中则直接返回缓存内容;若未命中则转发至源服务器,并将响应存入缓存。
- 非键输入(Unkeyed Input) :请求中不参与缓存键计算,但仍能影响源服务器响应的部分,如某些 HTTP 头(X-Forwarded-Host、X-Forwarded-Scheme 等)。
2.2 漏洞产生的根本条件
缓存投毒的发生需要同时满足以下条件:
- 存在非键输入:请求中存在不被纳入缓存键、但能被源服务器处理的输入。
- 非键输入可反射:该输入能够以某种形式反映在响应体中,或影响响应内容。
- 响应可被缓存:源服务器返回的响应被缓存服务器判定为可缓存。
当这三个条件同时成立时,攻击者即可构造恶意请求,使缓存中存储包含攻击载荷的响应。
2.3 攻击流程
攻击者构造恶意请求 → 缓存未命中 → 请求转发至源服务器
→ 源服务器返回含恶意内容的响应 → 缓存服务器存储该响应
→ 正常用户请求同一资源 → 缓存命中 → 用户收到恶意响应
三、常见利用手法
3.1 利用未键控头部注入
最常见的利用方式是通过 X-Forwarded-Host、X-Forwarded-Scheme、X-Host 等头部。例如,若应用根据 X-Forwarded-Host 生成页面中的资源链接,而该头部不参与缓存键计算,攻击者可将其设为恶意域名:
GET /en HTTP/1.1
Host: target.com
X-Forwarded-Host: evil.com
若响应中包含 <script src="https://evil.com/script.js">,且该响应被缓存,则所有访问 /en 的用户都会加载攻击者的脚本。
3.2 利用 Cookie 与参数解析差异
部分缓存服务器不将某些 Cookie 或查询参数纳入缓存键,但后端应用会读取这些值。攻击者可利用这种差异注入 XSS 载荷。
3.3 利用缓存键规范化差异
不同缓存服务器对 URL 的规范化处理不同(如对编码字符、路径穿越、参数顺序的处理),攻击者可构造特殊 URL 使缓存键与源服务器解析结果不一致,从而实现投毒。
3.4 组合攻击:缓存投毒 + XSS
最危险的场景是将缓存投毒与反射型 XSS 结合。攻击者将 XSS 载荷注入缓存,使所有访问该页面的用户自动执行恶意脚本,形成"存储型"效果,影响范围极大。
四、真实案例复盘
4.1 案例一:某大型 CDN 服务商缓存投毒(2018)
James Kettle 在研究中发现,多家使用主流 CDN 的网站存在缓存投毒漏洞。攻击者通过 X-Forwarded-Host 头部注入恶意域名,使缓存的页面包含指向攻击者服务器的资源引用。由于 CDN 边缘节点缓存了被污染的响应,大量用户受到影响。
根因:CDN 未将 X-Forwarded-Host 纳入缓存键,而源服务器信任该头部用于生成绝对 URL。
修复:CDN 厂商将相关头部纳入缓存键,或在边缘节点剥离不可信头部。
4.2 案例二:某电商平台缓存投毒导致 XSS(2019)
安全研究者在某电商平台的 404 页面中发现缓存投毒漏洞。攻击者通过构造包含 XSS 载荷的请求路径,使 404 页面被缓存。由于 404 页面通常被认为"无害"而设置较长缓存时间,攻击者成功将 XSS 载荷注入缓存,影响所有访问该路径的用户。
根因:缓存服务器将 404 响应也纳入缓存,且未对路径中的特殊字符进行规范化处理。
修复:对 404 响应设置 Cache-Control: no-store,并对 URL 进行严格规范化。
4.3 案例三:某云服务商缓存投毒(2020)
某云服务商的负载均衡器存在缓存投毒漏洞。攻击者利用 X-Forwarded-Scheme 头部将 HTTPS 请求标记为 HTTP,导致源服务器返回 301 重定向至攻击者控制的域名。由于重定向响应被缓存,所有用户被重定向至恶意站点。
根因:负载均衡器信任 X-Forwarded-Scheme 头部,且该头部不参与缓存键计算。
修复:在负载均衡器层面覆盖或剥离客户端提供的 X-Forwarded-* 头部。
五、防御策略
5.1 缓存层防御
- 扩大缓存键范围:将影响响应的所有输入(包括关键头部)纳入缓存键。
- 剥离不可信头部:在边缘节点移除或覆盖客户端提供的
X-Forwarded-*等头部。 - 严格缓存策略:对包含用户输入的响应设置
Cache-Control: no-store或private。
5.2 应用层防御
- 不信任代理头部:应用应仅信任来自已知代理的头部,或通过其他机制获取真实客户端信息。
- 输入验证与输出编码:对所有用户输入进行严格验证,对输出进行上下文相关的编码。
- 规范化 URL:确保应用与缓存服务器对 URL 的解析一致。
5.3 架构层防御
- 缓存键规范化:确保缓存服务器与应用服务器对请求的解析逻辑一致。
- 最小信任原则:任何中间层都不应无条件信任上游或下游传递的头部信息。
六、总结
Web Cache Poisoning 是一种危害大、影响范围广的攻击技术,其本质是利用缓存层与应用层之间的信任与解析差异。随着 CDN 和反向代理的广泛使用,该漏洞的攻击面持续扩大。防御的核心在于:确保缓存键覆盖所有影响响应的输入,并在架构层面建立严格的信任边界。对于安全从业者而言,理解缓存投毒的原理与利用手法,是保障现代 Web 应用安全的重要一环。
未经允许不得转载:任鹏个人博客 » Web Cache Poisoning 缓存投毒漏洞:原理、利用与真实案例复盘

