
网站接入 CDN 后,如果 A 用户看到 B 用户的昵称、订单或后台页面,应立即按潜在的信息泄露处理。先暂停受影响路径的边缘缓存,清理已经缓存的对象,再查响应头、缓存规则与缓存键。只让用户退出登录或清浏览器缓存,无法清除边缘节点里可能残留的私人响应。
先确认响应是从哪一层来的
用两个没有共享 Cookie 的测试会话访问同一个受影响 URL,记录时间、URL、请求头、状态码、响应头和页面中能够识别会话的最小字段。测试数据请使用专门创建的账号,不要把真实用户的订单或令牌贴进工单。若已发现真实数据串号,应同时按内部安全事件流程限制访问和保留证据。
在浏览器开发者工具的 Network 面板,重点看 Cache-Control、Age、Vary,以及 CDN 提供的命中标识,例如 CF-Cache-Status 或 CloudFront 日志中的缓存结果。Age 增长、CDN 显示 HIT,并且两个独立会话得到同一份私人内容,说明应优先检查边缘缓存;但单凭某个 HIT 响应头,不能证明敏感内容确实串号,还要比较响应体和访问链路。
用下面的命令检查匿名请求的响应头。测试登录态时,Cookie 和 Authorization 只能使用专门的测试凭证,不要把真实凭证写入终端历史或共享截图。
curl -sS -D - -o /dev/null 'https://www.example.com/account/'
随后从源站直连或绕过 CDN 的受控通道请求相同路径,对比响应头与内容。如果源站本身在不同会话中返回了同一用户数据,故障在应用或源站缓存;如果源站区分正确,只有经 CDN 的响应串号,继续查边缘规则。直连时仍须保留正确的 Host 与 TLS SNI,避免测到错误的虚拟主机。
登录页为什么会进共享缓存
CDN 用缓存键区分对象。常见缓存键包含主机名、路径和查询参数,但 Cookie 或 Authorization 是否参与,要看具体缓存策略。若 /account/、/api/me 等私人路径被“缓存全部内容”规则覆盖,且身份凭据未进入缓存键,不同用户就可能命中同一对象。即使把整个 Cookie 放进缓存键,也会造成高基数、低命中率,并不能代替阻止私人页面进入共享缓存。
HTTP 的 Cache-Control: private 表示共享缓存不得存储该响应;no-store 指示缓存不要存储响应。no-cache 允许存储,但复用前必须重新验证,它不等于“完全不缓存”。Vary: Cookie 可以让缓存按 Cookie 区分变体,但不宜把它作为保护账户页的唯一措施。存在显式边缘覆盖规则时,还须核对 CDN 产品实际的优先级。例如 CloudFront 的缓存策略如果把最小 TTL 设为大于 0,仍可能缓存带有 no-cache、no-store 或 private 的源站响应;不能只看源站响应头就认定边缘不会缓存。
另外,Set-Cookie 并不自动等于“所有共享缓存都安全绕过”。检查产品对这类响应头的处理方式,尤其是自定义缓存规则、Worker、反向代理和页面缓存插件是否改写了响应。
修复时按“止血、清除、验证”操作
第一步,在 CDN 为 /account/、/admin/、购物车、结账页和返回个人资料的 API 设置绕过缓存;实际路径以业务路由为准。还要检查通配路径是否覆盖这些例外,以及已登录用户访问的首页是否渲染个人信息。若账户信息混在首页 HTML 中,应调整应用渲染方式,或让该 HTML 也绕过共享缓存。
第二步,让源站为私人响应明确发送:
Cache-Control: private, no-store
这个响应头是防线之一,不能替代 CDN 端的路径与规则检查。公开静态资源继续按自身的缓存策略提供,不必把整站缓存都关闭。
第三步,清除受影响 URL 在 CDN 上的现存对象。确认是否有查询串、不同 Host、地区或设备变体;只清一个 URL,可能漏掉其他缓存键对应的对象。若产品支持按标签、前缀或完整 URL 清理,选能覆盖实际风险范围的方式。清除期间保留必要日志,记录规则变更和清理时间,避免破坏事件调查线索。
第四步,用两个新建的独立测试会话反复请求,检查是否仍出现跨账号字段;同时确认受影响路径为 BYPASS、DYNAMIC 或同类未命中状态,并检查应用日志没有错误地把会话内容缓存到服务器端。别用同一个浏览器配置文件的两个标签页做独立用户测试,它们通常共享 Cookie。
自建 Nginx 缓存还要检查两道开关
若 CDN 后面还有 Nginx proxy_cache,边缘不缓存也不能保证源站代理层安全。下例中的 session 只是示例 Cookie 名,必须按实际会话 Cookie 名和现有 proxy_cache 配置调整,并在测试环境验证:
location /account/ {
proxy_pass http://app_backend;
proxy_cache_bypass $http_authorization $cookie_session;
proxy_no_cache $http_authorization $cookie_session $upstream_http_set_cookie;
}proxy_cache_bypass 控制这次请求是否使用已有缓存;proxy_no_cache 控制这次响应是否写入缓存。对敏感路径,最直接的方案通常是不给它配置 proxy_cache,或显式 proxy_cache off;。修改配置前备份、执行 nginx -t,确认通过后再平滑重载;若异常,立即恢复原配置并复测。
复盘时把“公开静态资源”和“依赖用户身份的 HTML/API”分开管理。上线检查至少包含两个独立会话、匿名访问、CDN 命中状态和源站直连对照。只检查某一个账号访问正常,发现不了跨用户缓存污染。
参考资料
HTTP Caching(RFC 9111)、Amazon CloudFront 开发者指南、Cloudflare Cache-Control 文档及 NGINX proxy_cache 模块文档;资料核验于 2026 年 9 月 22 日。