2026 年 3 月 30 日,Railway 平台经历了一次严重的 CDN 缓存配置事故。在约 52 分钟的时间窗口内,约 0.05% 的域名因配置错误导致缓存被意外启用,使得本应直达源站的请求被缓存到边缘节点。这一事故造成了用户数据跨账户泄露的严重后果。本文将从技术细节、根因分析及工程防护三个维度,深度解读此次事故的教训与启示。

事故技术细节回顾

Railway 平台的 CDN 功能采用用户主动开启的 opt-in 模式,即默认情况下域名不启用边缘缓存,所有请求直接回源到应用服务器。然而,2026 年 3 月 30 日 10:42 UTC 的一次配置更新意外改变了这一行为。

工程师在对 CDN 提供商进行配置变更时,错误地将缓存策略应用到了已关闭 CDN 的域名上。这意味着这些域名的 HTTP GET 响应被存储在边缘服务器的缓存中,而按照正常逻辑,这些响应应该直接来自源站。由于 Railway 平台的部分响应包含用户身份相关的会话数据,虽然 Set-Cookie 响应头未被缓存,但大量缺乏明确 Cache-Control 指令的 GET 请求被默认缓存。

根据 Railway 官方的事故报告,受影响的域名占比约为 0.05%,时间窗口从 10:42 UTC 持续到 11:34 UTC。11:14 UTC 时,内部监控与用户反馈首次触发告警,11:34 UTC 配置变更被完全回滚并执行了全局缓存清除。

缓存失效机制的工程学思考

此次事故暴露了 CDN 缓存失效机制中的几个关键工程问题。首先是配置状态的不一致性:平台声称 CDN 默认关闭,但配置变更能够跨越这一状态边界,将禁用状态改为启用状态。这表明在配置下发流程中,缺乏对目标域名的状态校验机制。

其次是缓存行为的隐式默认。在缺乏显式 Cache-Control 头的情况下,边缘节点采用了默认缓存策略。这在正常业务场景中是合理的性能优化,但在用户已明确禁用 CDN 的前提下,这种默认行为实质上违背了用户意图。工程实践中,针对已声明禁用缓存的域名,边缘节点应当明确执行 no-store 指令,而非依赖默认缓存策略。

第三个问题是缓存数据的跨用户泄露。Cached GET 响应被不同用户请求复用,导致已认证用户的响应数据可能出现在未认证用户的设备上。这种缓存污染攻击在本质上与传统的缓存投毒类似,只是触发源来自平台自身的配置失误。

排查方法与应急响应

从事故响应时间线来看,从问题出现到首次识别相隔约 32 分钟,从识别到完全解决相隔约 20 分钟。这一时间窗口在缓存相关事故中属于中等水平,但考虑到数据泄露的严重性,仍有优化空间。

对于类似事故的排查,推荐以下技术路径:建立缓存命中率与源站请求量的实时监控仪表盘,当缓存配置发生变更时,监控源站请求量是否出现异常下降(表明更多请求被缓存),同时检查缓存命中率的突变情况。针对已禁用 CDN 的域名集合,应设置专项监控,当这些域名的缓存命中率超过阈值时触发告警。

应急响应层面,Railway 采取的措施是配置回滚加全局缓存清除。全局清除(Global Purge)是 CDN 供应商提供的标准能力,但执行成本较高,可能导致短时间内源站负载激增。工程团队在执行清除操作时,需要同步做好源站的容量预备。

工程防护措施建议

Railway 在事故后宣布了两项防护措施:一是增加生产环境变更前的缓存行为测试,二是将 CDN 变更的 rollout 从分钟级扩展到小时级,采用分片(shard)方式渐进推送。这两项措施分别针对测试覆盖不足和变更爆炸半径过大两个根因。

从更广泛的工程实践角度,建议补充以下防护手段。配置变更的事前校验方面,在将缓存配置下发到 CDN 边缘节点前,应增加目标域名状态的二次确认,确保配置意图与域名当前状态一致。变更执行的事中监控方面,对 CDN 配置变更建立专项监控指标,包括受影响域名的缓存命中率变化、源站请求延迟变化以及错误率波动。

事后审计方面,建议对每次 CDN 配置变更保留完整的变更日志,包括变更人、变更时间、变更参数以及影响范围。变更日志应当与缓存行为监控数据关联,便于事后回溯分析。

此外,针对用户数据的缓存边界,建议在应用层显式设置缓存控制策略。即使平台默认行为合理,应用自身也应当通过 Cache-Control 或 Surrogate-Control 头部明确声明缓存预期,避免依赖平台默认行为。

总结

Railway 此次 CDN 缓存事故是一次典型的配置错误引发的数据安全事件。事故的根因并非复杂的系统故障,而是配置下发流程中缺乏状态校验与变更防护。从工程实践角度看,这次事故提醒我们:缓存系统的配置变更必须具备状态感知能力,变更执行需要渐进式 rollout 策略,变更前后需要建立专项监控。任何看似简单的配置调整,都可能因为缓存系统的放大效应而产生远超预期的业务影响。

资料来源:Railway 官方事故报告(Incident Report: March 30th, 2026 — Authenticated user data cached)