← 中文资源

简体中文版本

调试用户之间的缓存串号问题

用两个身份交叉请求证明共享缓存把 A 的个性化响应发给了 B,再修复缺失的 Vary 头并验证隔离恢复。

阅读英文原文

目标

用户间的缓存串号对单个测试者是不可见的:团队共用一个账号,错误的个性化数据看起来反而正确。探测器就是两个账号加两次 curl。先以 Alice 身份请求同一 URL,再以 Bob 身份不带任何绕缓存参数请求;如果 Bob 仍看到 Alice 的名字,说明共享缓存把个性化响应存进了公共键,缺失的 Vary 头就是根因。

步骤要点

  1. 用 TOKEN_A 请求个性化端点,记录 displayName(如 Alice)。
  2. 用 TOKEN_B 请求同一 URL,不加任何 cache-busting 参数:仍显示 Alice 即坐实缓存串号。
  3. 检查该响应的 Cache-Control/Vary/Age 头:允许共享缓存却没有 Vary: Authorization,加上 Age 偏大,构成完整解释。
  4. 在源站为该路由补上 Vary: Authorization 并把 Cache-Control 改为 private, max-age=60。
  5. 清除受污染缓存条目后重跑两账号测试:Bob 看到 Bob、Alice 看到 Alice、每个响应都携带 Vary 头。

排错提示

加了 Vary 但 CDN 仍返回旧内容,是改动前入缓的条目要等 TTL,应 purge 该路径或提升缓存键版本;修复导致命中率崩塌时,把响应拆成“公共外壳 + 私有个性化片段”,只对片段应用 Vary/private;Cookie 会话同样会泄漏,要对实际使用的 Cookie 名做 Vary,且凭证请求未经 private 指示绝不入共享缓存。

适用边界

Vary 会把缓存条目按头值数量倍增,高基数头可能把缓存切得毫无价值;两个账号只能证明这两个身份存在泄漏,所有个性化端点都应系统性审计。

代码示例

# As user A
curl -s https://api.example.com/me/header -H "Authorization: Bearer $TOKEN_A"

# As user B — if this prints Alice, the cache is leaking
# Check the headers that allowed it
grep -iE "cache-control|vary|age" /tmp/hdrs