反向代理缓存投毒漏洞,Nginx

反向代理缓存投毒漏洞,简单说就是攻击者利用缓存键(cache key)覆盖不完整或URL解析差异,把恶意页面的内容“塞进”代理缓存,让正常访客也拿到被污染的数据。
这类问题在配置了 Nginx proxy_cache 的站点中并不少见,往往不是缓存功能本身的锅,而是安全参数没跟上。
本文用零基础也能照做的方式,带你理解漏洞成因、加固 proxy_cache 关键参数,并完成效果验证。

缓存投毒为什么会发生

Nginx 的缓存键默认基于请求路径和部分请求头生成,比如 scheme://host$request_uri
如果配置里没有显式定义 proxy_cache_key,不同 Host 或端口可能共用缓存键,导致跨域污染。
此外,Nginx 对 URL 规范化有自己的规则,攻击者利用 ///../%2f 等变体会让缓存键与上游实际请求路径不一致,从而篡改缓存内容。

正常情况下,只有当缓存命中条件、缓存键和上游响应来源三者都校验正确时,才能放行缓存;
否则就需要通过参数收紧规则。
明白了这一点,下面的配置就有了明确目标。

加固 proxy_cache 的关键参数

核心思路就是让缓存键更精确、响应更可信、并发回源更受控。
建议在 nginx.conf 的 http 块中统一规划,然后在具体 server 或 location 中生效。

  • proxy_cache_key:必须显式定义,避免多个虚拟主机共用默认 key。推荐格式如下:
set $cache_key $scheme://$host$request_uri;
proxy_cache_key $cache_key;
  • proxy_cache_valid:只缓存指定状态码,比如 200 302 60m;,不要默认缓存全部状态码。
  • proxy_cache_lock:开启后同一时间只允许一个请求回源,其他请求等待,避免缓存失效时并发穿透。
  • proxy_cache_revalidate:用 If-Modified-Since 条件请求替代完整响应,减少缓存过期后的重复拉取。
  • proxy_hide_header:隐藏上游返回的敏感响应头,比如 Set-CookieX-Accel-Redirect,防止被写入缓存。
  • proxy_ignore_headers:按需忽略上游 Cache-Control 等头,避免上游控制权过大覆盖本地策略。

其中 proxy_cache_keyproxy_hide_header 是防投毒最直接的两个参数,务必优先配置。

实战配置示例

下面是一段兼顾安全与性能的反向代理缓存配置片段,可直接调整后使用:

http {
    cache_key_zone my_cache:10m;

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_cache my_cache;
            proxy_cache_valid 200 302 60m;
            proxy_cache_key $scheme://$host$request_uri;
            proxy_cache_lock on;
            proxy_cache_revalidate on;

            proxy_hide_header Set-Cookie;
            proxy_hide_header X-Accel-Redirect;
            proxy_ignore_headers Cache-Control Expires Set-Cookie;

            proxy_pass http://127.0.0.1:8080;
            proxy_set_header Host $host;
        }
    }
}

注意:proxy_cache_key 里包含 $host 后,不同域名即使路径相同也不会互相污染。
若使用 HTTPS,建议补上 $scheme,防止 http/https 混存。

验证缓存是否安全生效

配置完成后重新加载 Nginx:

nginx -t && nginx -s reload

然后用 curl 检查响应头里的缓存标记:

curl -I http://example.com/

若看到 X-Cache-Status: HITX-Cache: HIT,说明缓存已命中。
再做一次投毒探测,访问以下变体地址:

curl -I http://example.com/%2f%2fnormal-path/

如果这些地址返回的缓存响应与正常 URL 完全一致,说明缓存键定义有效,没有被绕过。若发现变体地址生成了独立缓存条目,就要检查 proxy_cache_key 是否还是默认值。

避坑指南与常见疑问

很多用户配置后遇到“缓存不生效”或“缓存了登录态”,多是没有处理 Set-Cookie
如果你希望公共缓存完全避开带登录态的请求,可以在 proxy_cache_key 中加入 Cookie 判断,但性能会下降;
更稳妥的做法是直接 proxy_hide_header Set-Cookie,同时只缓存 200 和 302。

另一个常见疑问是:能不能靠 proxy_cache_valid 200 就完全防投毒?
答案是不能。
它只控制缓存时长,不管缓存内容是否被篡改。真正决定投毒风险的是缓存键精确程度和上游校验逻辑,两者必须配合使用。 另外,Nginx 官方文档对 proxy_cache 各参数的说明会随版本微调,具体以你所用版本的官方文档为准,不要照抄旧配置。

如果你现在正准备处理 396.反向代理缓存投毒漏洞,建议先把文中的配置逐行核对自己的 server 块;
遇到缓存命中异常时,优先查看 proxy_cache_keyproxy_hide_header 两个参数,再结合 curl 返回值定位问题。
安全加固没有一劳永逸,定期检查和更新配置才是长期有效的做法。

分享到:
上一篇
服务器文件完整性监控,检测系统关键文件被篡改脚本
下一篇
数据库账号只允许业务服务器IP访问
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意