LOADING

加载过慢请开启缓存 浏览器默认开启

Cloudflare为了防御 React2Shell (CVE-2025-55182) 而引发的全球中断

距离上一篇写 Cloudflare全球互联网瘫痪:安全升级的好心办坏事 还没满一个月,Cloudflare 的 Status Page 在 12 月 5 日又红了一片。

上次是因为代码发布的流程问题,而这次的情况稍微复杂点——简单来说,是为了修补一个紧急漏洞,结果把网给修断了。SRE 最不想遇到的经典电车难题:是要安全性,还是要可用性?

结合官方刚出的 Post-mortem 和最新的 CVE 信息,简单记录一下这次持续了 25 分钟的全球中断。

背景:React2Shell (CVE-2025-55182)

如果不看这个漏洞,就没法理解 Cloudflare 为什么操作得这么急。

12 月 3 日,React 团队披露了 CVE-2025-55182,社区里叫它 “React2Shell”。这是一个针对 React Server Components (RSC) 和 Next.js 的反序列化漏洞。攻击者即使没有权限,也能通过构造特定的 HTTP 请求在服务端执行代码。

因为利用门槛低,从 AWS 和 CISA 那边传来的消息看,漏洞披露没多久野外就已经开始有扫描和利用尝试了。对于托管了大量 Next.js 应用的 Cloudflare 来说,如果不拦截,很多客户的源站会被打穿。

事故过程

发生时间:2025-12-05 08:47 UTC - 09:12 UTC
影响:全球约 28% 的 HTTP 流量返回 500 错误。

事情的经过大概是这样:

  1. 起因:为了拦截针对 React2Shell 的攻击 Payload,Cloudflare 安全团队决定调整 WAF 的检测逻辑。这涉及到改变 WAF 解析 HTTP Body 的方式,以便更早识别出恶意的序列化数据。
  2. 变更:08:47 UTC,工程师下发了一个全局配置变更。注意是全局,没有按常规的灰度流程走(Canary),原因是为了抢在攻击扩散前生效。
  3. 触发问题:这个变更本身在测试环境没问题,但到了生产环境,撞上了 Cloudflare 的历史包袱。在部分尚未迁移的新架构(FL1 架构)节点上,如果客户同时开启了 Cloudflare Managed Ruleset,新的 Body 解析逻辑会抛出一个未捕获的异常。
  4. 爆发:配置推送到全球节点大约只需要几秒钟。紧接着,大量请求开始直接返回 500 Internal Server Error
  5. 恢复:09:12 UTC,变更回滚完成,服务恢复。

为什么会这样?

看 Cloudflare 的 CTO Dane Knecht 的复盘,核心还是那个老生常谈的矛盾:紧急止血 vs 变更稳定性

这次变更使用的是 Cloudflare 的全局配置系统(Global Configuration System)。这个系统的特点就是快,专门用来应对 0-day 漏洞的。但它的缺点也很明显:它绕过了常规的分批次发布流程。

这里有两个关键点值得留意:

  1. 特定的触发条件:只有走 FL1 旧架构 + 开启托管规则集的流量才会挂。这种特定组合在 Staging 环境可能确实覆盖不全,也就是所谓的“边缘情况”(Edge Case)。
  2. 没有金丝雀:平时我们做变更,都要先在一个数据中心跑跑看。但这次为了防御 RCE,Cloudflare 选择了跳过这一步。如果不跳过,可能客户已经被黑了;跳过了,结果把自己搞挂了。

写在最后

短短两个月内连续两次大规模中断,虽然原因完全不同,但对用户的信心打击挺大。

对我们来说,这次事故有两个比较现实的提醒:

第一,别太依赖 WAF。WAF 只是挂在前面的盾牌,这次盾牌自己碎了还砸伤了人。如果你的业务用了 Next.js 15/16 或者 React 19,赶紧把官方补丁打了(React 19.2.1+),源站安全才是兜底的根本。

第二,SRE 的无奈。当你手握一个能在这个星球上秒级生效的配置开关时,每一次回车都需要巨大的勇气。这次 Cloudflare 赌输了,但如果他们动作慢了导致大量客户被入侵,那又是另一个故事了。


参考资料: