文章总结: 本文系统解析CPDoS缓存投毒拒绝服务攻击,通过恶意HTTP头使缓存存储错误页面,导致所有用户访问被阻断。详述HHO、HMC、HMO三种攻击手法及组合利用方式,并给出统一header大小限制、禁用方法覆写头、缓存不存错误页等防御建议。 综合评分: 88 文章分类: WEB安全,漏洞分析,实战经验
CPDoS缓存投毒拒绝服务:让所有用户看到错页的隐蔽攻击
原创
Red Hunter Red Hunter
黑白之道
2026年10月4日 09:39 韩国
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
导语:SQLi 能偷数据,XSS 能劫持会话——这两类攻击大家都熟。但 CPDoS 这种”投毒缓存让所有用户看到错页”的攻击,名气小得多,危害却能直接打瘫一整个网站。一次请求,整站缓存报废。
一、什么是 CPDoS
CPDoS(Cache Poisoned Denial of Service,缓存投毒拒绝服务)是 Web Cache Poisoning(Web 缓存投毒)家族里专门服务”拒绝服务”目标的子分支。和 SQLi 这种”立刻看到数据外泄”的攻击不一样,CPDoS 的核心动作是:让缓存替攻击者把错误页面”合法化”。
受害者不知道自己中毒,源站日志一切正常,但所有访问目标页面的合法用户都被挡在门外。完整资料参考 cpdos.org。
二、攻击链 6 步拆解
CPDoS 的工作流非常清晰:
- 攻击者发一个带恶意 header 的 HTTP 请求(任何 header 都行)
x-mal-example: tohackthehacker
- 请求先到中间缓存(CDN / 反向代理),缓存查不到目标资源的副本
- 缓存把请求原样转发到源站
- 源站因为畸形请求返回错误页(400 / 405 / 500)
- 缓存把这个错误页当成”目标资源的最新副本”存下来
- 后续所有合法用户访问这个资源,缓存都都返回错误页
源站本身没被攻破,数据也没泄露,但整个缓存层的视图被毒化。重启缓存才能恢复——这比 SQLi 的修复成本高得多。
三、三种 CPDoS 攻击手法
3.1 HHO(HTTP Header Oversize,HTTP 头超长)
HTTP 协议本身没有规定 header 大小上限。这给攻击者留了一个天然的”大小不一”裂缝:
- 缓存 容忍的 header 长度:8KB / 16KB(Cloudflare 默认 16KB)
- 源站 容忍的 header 长度:可能只有 4KB / 8KB(IIS、Nginx 默认值)
攻击者构造一个比源站大、比缓存小的 header,缓存收到觉得没问题,转发给源站,源站处理不了返回 Header Size Exceeded,缓存把 400 错误页存下来。
PoC:
GET / HTTP/1.1
Host: target.com
X-Oversized-Header-x: <8KB 随机字符串>
这种攻击对未限制 header 大小的源站(尤其是 IIS、Express 默认配置)几乎一击必杀。
3.2 HMC(HTTP Meta Characters,HTTP 元字符注入)
不靠大小,靠元字符让源站拒绝解析:
GET / HTTP/1.1
Host: target.com
X-Meta-Malicious-Header: \r\n
\r\n、\n、\a 这些元字符塞进 header,缓存接受(透传不解析),但源站严格按 RFC 解析时直接抛 character not allowed 错误。同样的剧本,错误页替换掉合法响应。
HMC 比 HHO 更隐蔽——头部大小看起来完全正常,单纯看大小检查根本抓不到。
3.3 HMO(HTTP Method Override,HTTP 方法覆写)
HTTP 标准里有一组”方法覆写”头,让代理在转发请求时把方法改成 header 里指定的值:
X-HTTP-Method-OverrideX-HTTP-MethodX-Method-Override
这三个 header 在 Rails、Django、Express、Spring Boot 等主流框架里都默认支持。攻击流程:
POST /api/users HTTP/1.1
Host: target.com
X-HTTP-Method-Override: DELETE
如果源站 API 没实现 DELETE 方法(很多只允许 GET/POST),就会返回 405 Method Not Allowed。缓存把 405 存住 → 后续所有合法 POST 请求都被挡在缓存层。
HMO 在 REST API 接口上尤其危险,因为 REST API 经常出现”某些方法没暴露但方法覆写头被启用”这种配置错位。
四、组合拳:H-b-H 头 + CPDoS
Day-10 讲的 Hop-by-Hop 头滥用可以跟 CPDoS 联动:
Connection: close, X-Oversized-Header-x
CDN / 反代看到 Connection 头里列出了 X-Oversized-Header-x,按 H-b-H 规则把它从转发请求里剥掉。但缓存自己那一层处理请求时已经”读到了”它的转发逻辑,把请求当成合法资源存起来。结果是:
- 缓存存的是”无恶意 header 时的正常响应”
- 但缓存实际存的内容对应的请求和真实用户请求的语义不一样
这种协议层语义不一致会让缓存行为完全不可预测,是更高级的 CPDoS 玩法。
五、实战记录(HackerOne 报告)
CPDoS 在真实漏洞赏金里已经被多次确认有效:
- #409370 — Cloudflare + 源站头大小不一致
- #728664 — Akamai + Rails 框架
- #921704 — Fastly + Spring Boot
- #326639 — Cloudflare + IIS 头大小
- #591302 — AWS CloudFront + Django
这些报告的共同点是:头部大小或方法覆写机制差异被利用,企业级 CDN 都在名单上。
六、防御要点
CPDoS 的根治要从缓存层和源站层两端同时收紧:
- 统一 header 大小限制:缓存和源站配置相同的
large_client_header_buffers(Nginx)/MaxRequestHeadersSize(IIS) - 禁用方法覆写头:除非业务明确需要,否则在反代层把
X-HTTP-Method-Override系列头直接 drop - 缓存不存错误页:明确配置缓存只存 2xx / 3xx,4xx / 5xx 不缓存
- 缓存键包含 header:避免攻击者的恶意 header 被混入缓存键
- 元字符过滤:源站解析 header 时对
\r\n、\n、\0等做严格检查 - WAF 规则:拦截 header 中包含元字符或长度异常的请求
CPDoS 不需要 SQLi 那种复杂利用链,也不需要 0day。一行特殊 header,整个网站就被打瘫——这是它最危险的地方,也是最容易被忽视的地方。
原文出处:learn365 Day-11 Cache Poisoned Denial of Service (CPDos) 综合参考:cpdos.org · PortSwigger CPDoS 研究
👇 点击阅读原文,访问我的网站
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:黑白之道 Red Hunter Red Hunter《CPDoS缓存投毒拒绝服务:让所有用户看到错页的隐蔽攻击》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论