Skip to content
Kurisu
Go back

React2Shell:从 Thenable 到 WAF 绕过

Next.js Conf 2023 上团队演示 RSC 时,推特就吵过一轮「前端也能写后端漏洞」——如今一语成谶。

之前写过 Next.js CVE-2025-29927(middleware 鉴权绕过),那是”门卫”问题;React2Shell 是另一个量级——React Server Components(RSC)链路的 RCE。原文为五篇连载,作者参与应急并拿下 Vercel 官方 WAF 绕过活动奖金。

0x01 前置:从回调地狱到 Thenable

  1. 回调地狱:古早 API 全靠回调,登录拿token → 查用户id → 查订单 层层嵌套;
  2. Promise(ES6):嵌套变链式,then() 让回调回到同一上下文;
  3. Thenable:任何实现了 then() 方法的对象。React 处理数据时会检查”值是不是 Thenable,是就调用它的 then”——漏洞引信就是它。

0x02 SSR vs RSC:前端怎么写出了后端漏洞

攻击面:Flight 的解析端是服务端代码,处理的却是可被伪造的客户端数据。

0x03 应急视角:为什么 SCA 扫不到这个组件

  1. 按通告排查 react-server-dom-webpack 等组件——npm 日志 + SCA(软件成分分析)都没有命中;
  2. 公司明明有 Next.js 业务:RSC 对 Next.js 属可选依赖,开发没装;
  3. 拿 Vulhub 源码调试验证 → Next.js 把第三方依赖直接打包进 compiled 目录,SCA 清单里看不到 react-server-dom-webpack。

教训:框架自打包依赖会绕过成分分析,SCA 说”没有”不等于”不受影响”,要以调试为准。

0x04 Flight 协议:Chunk 是怎么被解析的

RSC 数据包由一个个 Chunk 组成,解析流程:

遍历 multipart 字段
  → 每个字段 JSON.parse() 成对象
  → 递归遍历所有子孙结构
  → 发现 $ 开头的值 → 按规则互相"引用"(扩展 JSON 不支持的类型:函数/组件/Thenable…)
  → 结果放进 chunk.value,作为"数据"

$ 前缀引用是 Flight 对 JSON 的类型扩展,也是攻击者往解析里塞逻辑的入口。

0x05 漏洞本质:还是”混淆数据和业务逻辑”

万能公式:SQL 注入是输入变成 SQL、命令注入是输入变成命令、XSS 是输入变成 HTML——React2Shell 是攻击者的”数据”变成了服务端的”Chunk 对象”。

POC:POST 一个 multipart 请求(Next-Action: x 头 + Content-Type: multipart),用 $ 引用构造出带 constructor 的原型链,让解析器把攻击者控制的”数据”识别成可调用对象(Thenable/函数路径),触发执行 → RCE。

JSON.parse 的产物本该只是数据,$ 引用 + 原型链让解析器亲手把它升格成了逻辑。

0x06 15 万美元的 WAF 绕过

思维实验级

工程级

0x07 小结与防守清单

相关旧文


Share this post:

Previous Post
框架漏洞选题:WordPress、ThinkPHP 与织梦
Next Post
一次真实渗透测试的完整流程