防御web缓存中毒的核心是切断“恶意输入→被缓存→污染其他用户”链,关键在于严格控制缓存键生成、净化响应内容、限制不可信输入参与缓存决策,包括白名单校验http头、禁用易伪造字段、防止反射型xss、启用csp与sri、部署waf检测及缓存行为监控。

要防御 Web 应用缓存中毒引发的注入风险,核心不是“堵住某一个入口”,而是切断“恶意输入 → 被缓存 → 污染其他用户”的传播链。关键在于控制缓存键的生成逻辑、净化响应内容、限制不可信输入参与缓存决策。
严格校验并最小化缓存键来源
缓存中毒的根本诱因是缓存系统把不该纳入缓存键(cache key)的请求头或参数当成了区分资源的依据。比如 Host、X-Forwarded-Host、Accept-Language、Cookie 中的 locale 字段,一旦被用于生成缓存键且未校验合法性,就极易被操控。
- 只将明确可控、业务必需的字段纳入缓存键,如 URL 路径和标准化后的查询参数(如 ?id=123),禁用 Host、Referer、User-Agent 等易伪造字段
- 对参与缓存键的 HTTP 头做白名单校验:例如仅允许 Accept-Language 值为 en、zh、ja 等预设语言码,拒绝任何含 script 标签、JavaScript 关键字或非 ASCII 字符的值
- CDN 或反向代理层(如 Nginx、Cloudflare)配置中显式忽略高风险头,例如:
proxy_cache_key "$scheme$request_method$host$request_uri";,不包含 $http_x_forwarded_host
避免反射型内容直接进入响应体
缓存中毒常与 XSS 协同起效——攻击者构造带恶意脚本的请求,该响应被缓存后,所有访问相同缓存键的用户都会执行脚本。因此,任何将请求数据(尤其是 header、query、cookie)原样输出到 HTML/JS/CSS 中的行为都必须杜绝。
- 禁止将 X-Forwarded-Host、Referer、User-Agent 等头字段直接插入页面 DOM 或内联 script;如需展示,必须 HTML 编码 + 严格长度截断
- 服务端模板渲染时,对所有动态插入的变量启用上下文敏感转义(如 HTML 属性内用双引号包裹并实体编码,JS 上下文中用 JSON.stringify)
- 静态资源(CSS/JS)禁止通过 query 参数动态生成内容,避免类似
/script.js?callback=alert(1)这类可缓存又可执行的模式
启用缓存层级的内容完整性控制
即使缓存被污染,也应确保恶意内容无法生效。这需要在传输与解析环节增加验证机制。
- 对所有 HTML 响应强制启用 Content-Security-Policy(CSP),禁止内联脚本('unsafe-inline')、禁止 eval,并指定可信的 script-src 域名
- 为关键接口设置 Cache-Control: private, no-store 或 no-cache,明确告知 CDN/浏览器不得缓存含用户个性化数据的响应
- 使用 Subresource Integrity(SRI)为外链 JS/CSS 添加哈希校验,防止 CDN 节点返回篡改后的资源文件
部署运行时防护与监控闭环
单靠开发阶段的编码规范难以覆盖所有边缘场景,需结合网关层防护与持续可观测性。
- 在 WAF 或 API 网关开启“Header 注入检测”规则,拦截含 javascript:、data:text/html、onerror= 等典型 XSS payload 的请求头
- 定期扫描缓存行为:用不同 Host、X-Forwarded-Host、Accept-Language 发起探测请求,比对响应是否一致;若出现“相同路径返回不同内容”,即存在缓存键污染风险
- 记录所有被缓存的响应的原始请求头摘要(如 Host+Accept-Language 的 SHA256),一旦发现异常响应,可快速定位污染源头











