Magento 2 接入 CDN 后,偶尔有人反馈“登录后看到别人的名字”“购物车数量跳来跳去”或“退出后账户页还能打开”。这不是普通缓存不一致,而是潜在的数据泄露事件。公共 HTML 缓存一旦包含客户专属内容,影响可能跨账号、跨地区持续扩散。

最危险的信号

不同浏览器请求同一 URL,响应 HTML 中出现相同客户姓名、邮箱、地址片段或订单号;/customer/account/、checkout、wishlist、compare 等路径带有 CDN HIT;响应包含 Set-Cookie 却仍被共享缓存;登录与未登录请求使用相同 cache key。这些现象出现任何一个,都应按安全事件止损,而不是等用户刷新。

先旁路,再保留证据

立即对账户、购物车、结账、API 和自定义会员路径设置 bypass/no-store,并 purge 相关缓存对象。保留 CDN 请求 ID、时间、POP、cache status、URL、匿名化后的请求头和响应头,避免保存不必要的个人数据。若确认跨客户泄露,应启动公司的隐私与安全响应流程。

curl -sSI https://www.example.com/customer/account/
curl -sSI -H 'Cookie: PHPSESSID=REDACTED' https://www.example.com/customer/account/

不要把真实 session cookie 写进工单或 shell history。测试应使用专门测试账号和短期会话。

Magento 的 private content 解决不了错误的整页规则

标准可缓存页面把迷你购物车等客户信息放在浏览器端 customer-data section 中,公共 HTML 本身不应包含敏感值。但自定义 block 直接读取 customer session、模板输出姓名,同时仍允许整页缓存,就会污染 FPC。即使 Magento 源站返回正确的 private/no-cache,CDN 的“cache everything”规则也可能覆盖它。

检查布局 XML 中 block 的 cacheable 设置、自定义 controller 的响应头,以及 CDN 是否尊重 Cache-Control: private, no-store, no-cache。不要用给所有页面加随机参数的方式规避,这会摧毁缓存命中率且仍可能遗漏入口。

缓存键不能只由 URL 组成

可公开缓存的 Magento 页面还会受 store、currency、客户组等上下文影响。CDN 如果剥离必要 cookie 却不把等价上下文加入 cache key,会把一个维度的页面发给另一个维度。客户个人身份通常不应该进入公共 cache key,而应直接绕过缓存;否则对象数量爆炸,也更难彻底 purge。

检查重定向和错误页

账户页未登录时常返回登录页或重定向。CDN 若缓存 302,可能导致已登录客户持续被送回登录;反过来,缓存鉴权后的 200 会暴露内容。支付回调、失败页、订单成功页也不能被共享缓存。尤其要检查忽略 query string 的规则,成功页 token 被删掉后可能发生串页。

如何证明修复有效

准备测试账号 A、B 和无痕访客,在不同会话、不同 POP 条件下依次访问公共商品页与私有页面。公共页应按设计 HIT,私有页应 bypass/dynamic;A 的响应体与 customer-data 不能出现于 B。再测试登录、退出、切换币种、切换 store、购物车更新和订单成功路径。

最后检查 CDN 配置变更的版本记录和自动化测试。可以在部署后用合成监控断言账户路径从不返回 HIT,并扫描响应中是否出现测试账号标记。这样的监控比等真实客户截图更早发现回归。