智能工具库

React Flight协议反序列化漏洞实战与防御

本文深入解析React Server Components的Flight协议反序列化漏洞,揭示CVSS 10.0“React2Shell”的攻击原理,并提供实用的防御策略,帮助开发者构建更安全的RSC应用。

2026-07-21 0来源:Smashing Magazine

从Flight协议到React2Shell:一次反序列化攻击的解剖

React Server Components(RSC)凭借其Flight协议,实现了服务端到客户端的交互式UI流式传输,极大提升了开发体验。然而,这一创新机制也悄然引入了反序列化风险,甚至催生了CVSS评分高达10.0的“React2Shell”漏洞。作为开发者,理解这一攻击链路并掌握防御方法,已不再是可选项,而是必备技能。

Flight协议:交互的桥梁,也是攻击的入口

Flight协议本质上是React自定义的序列化格式,用于在服务端和客户端之间传递组件树、props和状态。它支持复杂数据类型(如Map、Set、日期)的传输,并允许通过特殊标记引用客户端组件。这种灵活性正是攻击者垂涎的目标——当协议数据被恶意篡改时,解析器可能执行非预期操作,例如构造任意对象或触发危险函数。

Durgesh Pawar在Smashing Magazine的文章中详细拆解了React2Shell的攻击链:攻击者通过控制Flight数据流中的特定字段,诱使解析器反序列化出恶意对象,进而利用React内部机制(如createElementSymbol处理)实现远程代码执行(RCE)。整个过程无需用户交互,且能绕过传统XSS过滤,危害极大。

漏洞根源:反序列化“下沉点”无处不在

反序列化“下沉点”指的是解析器在还原数据时,会调用某些可被利用的函数或属性。在Flight协议中,这些下沉点包括:

  • 自定义解析器:React允许开发者注册自定义类型解析器,若这些解析器未做严格校验,攻击者可能注入恶意载荷。
  • $$typeof符号处理:Flight使用$$typeof标记区分组件类型,攻击者可伪造该字段,诱导解析器调用特定工厂函数。
  • 服务端组件引用:当客户端引用服务端组件时,协议会传递组件ID和props,若ID被篡改,可能触发服务端任意模块加载。

对开发者而言,这意味着任何接受外部输入的RSC应用(如SSR渲染的页面、API返回的数据)都可能成为攻击面。尤其在使用第三方RSC库或自研协议扩展时,风险成倍增加。

防御策略:从协议设计到运行时加固

面对这类漏洞,单纯依赖React官方补丁并不足够,开发者需要系统性防御:

  1. 严格限制输入源:只信任来自已知服务器的Flight数据,对客户端提交的数据进行签名或加密验证。
  2. 禁用或白名单化自定义解析器:除非绝对必要,避免注册自定义类型解析器;若必须使用,则对传入类型进行白名单校验,拒绝未知类型。
  3. 隔离服务端组件引用:对组件ID进行映射,不允许直接使用原始字符串,防止路径遍历或模块注入。
  4. 运行时监控与沙箱:在解析Flight数据时,使用vm模块或Web Worker等沙箱环境,限制代码执行权限,即使反序列化成功,也无法访问敏感API。
  5. 保持依赖更新:密切关注React安全公告,及时升级到修复版本,但不要依赖补丁作为唯一防线。

实战建议:审计你的RSC应用

如果你正在使用或计划使用RSC,建议立即执行以下审计:

  • 检查所有Flight数据来源,确认是否有可能被用户控制。
  • 搜索代码中是否有parseFlightdecodeAction等关键函数,并审查其输入验证逻辑。
  • 使用自动化工具(如npm audit)扫描依赖项,关注React相关漏洞库。

对于安全研究员,理解Flight协议的反序列化机制,也能帮助你发现更多类似漏洞。建议深入研究React源码中的ReactFlightClient.jsReactFlightServer.js,寻找新的下沉点。

结语

React2Shell漏洞不是孤例,它揭示了现代前端框架在追求性能与体验时,往往以牺牲部分安全性为代价。作为开发者,我们需要在拥抱新技术的同时,保持对协议底层机制的敬畏。通过本文的剖析,希望你能在构建RSC应用时,将安全视为一等公民,而非事后补救。

本文基于 Smashing Magazine 的公开内容,由 AI 辅助整理改写后发布。

原标题:Weaponizing And Defending The React Flight Protocol: Deserialization Sinks In RSCs

阅读原文