React2Shell (CVE-2025-55182): The Deserialization Ghost in the RSC Machine

React2Shell (CVE-2025-55182): The Deserialization Ghost in the RSC Machine 👻⚛️
In the final weeks of 2025, while most engineering teams were preparing for the holiday freeze, a vulnerability emerged that redefined modern web security. Dubbed “React2Shell” and tracked as CVE-2025-55182, this flaw wasn’t just another bug—it was a fundamental breakdown in the trust model of React Server Components (RSC).
With a CVSS score of 10.0, React2Shell allows unauthenticated attackers to achieve Remote Code Execution (RCE) through a single, specially crafted HTTP request. Much like the infamous Log4Shell of 2021, the danger lies in its ubiquity and the “silent” nature of the underlying protocol.
In this deep dive, we explore the mechanics of the RSC “Flight” protocol, the deserialization flaw that opened the door to chaos, and how you can protect your infrastructure in 2026.
1. What is the RSC Flight Protocol?
To understand React2Shell, we first have to understand the Flight Protocol.
Traditionally, React apps sent JSON or HTML. With the advent of React 19 and the App Router, React introduced React Server Components (RSC). RSCs allow the server to render UI components and stream them to the client in a proprietary format called Flight.
How Data Moves in Flight
When a client requests an RSC or invokes a “Server Action,” the server doesn’t just send HTML; it sends a stream of serialized JavaScript objects. These objects represent:
- Component Trees: The structure of your UI.
- Props: Data passed to components.
- Server References: Identifiers for functions that can be called on the server.
- Promises: Placeholders for data that hasn’t arrived yet.
The Flight protocol uses a specific syntax where lines are prefixed with IDs (e.g., 1:, 2:) and special symbols like $@ for references or $B for Blobs.
The server-side decoder (found in packages like react-server-dom-webpack) is responsible for taking incoming client data—such as arguments for a Server Action—and reconstructing them into JavaScript objects that the server can use. This is where the ghost was hiding.
2. The Vulnerability: CVE-2025-55182 Explained
The root cause of React2Shell is an unsafe deserialization flaw. Specifically, the React server-side decoder failed to validate object properties during the reconstruction of the Flight stream.
Prototype Pollution on the Server
The vulnerability leverages a classic JavaScript weakness: Prototype Pollution. In JavaScript, almost every object inherits from Object.prototype. If an attacker can inject properties into the prototype, they can change the behavior of every object in the system.
During the decoding process, React used property names supplied by the incoming Flight payload to access values without verifying if those properties belonged to the object itself (i.e., it lacked hasOwnProperty checks).
The Flaw: By crafting a payload that referenced properties like __proto__ or shadowing internal methods like then, an attacker could trick the React runtime into traversing the prototype chain and executing unauthorized functions.
3. Anatomy of the Exploit: From Request to Shell
The brilliance—and terror—of React2Shell is that it requires no authentication. An attacker simply finds an endpoint that accepts RSC payloads (which is almost any route in a default Next.js App Router application) and sends a POST request.
The Attack Chain
Researchers identified a four-stage “gadget chain” that turns this deserialization bug into a full shell:
Stage 1: The Self-Referential Loop: The attacker sends a multipart/form-data request containing a “fake chunk” object. This object mimics React’s internal Chunk class.
Stage 2: Property Shadowing: The payload sets the then property of this fake chunk to reference Chunk.prototype.then. This creates a circular reference that forces the server to “await” the object.
Stage 3: The Blob Handler ($B): The attacker uses the $B prefix (reserved for Blobs) to trigger a specific internal React function. This function is tricked into looking up a malicious reference.
Stage 4: Code Execution: By chaining these gadgets, the attacker gains access to the Node.js process or child_process modules. They can then execute system commands like whoami, curl, or even launch a reverse shell.
A Sample (Conceptual) Malicious Payload:
POST /api/server-action HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary
Next-Action: [Action_ID]
------Boundary
Content-Disposition: form-data; name="0"
{"then":"$1:__proto__:then","status":"resolved_model","value":"payload_here"}
------Boundary
Content-Disposition: form-data; name="1"
"$@0"
------Boundary--
Note: This is a simplified representation. Real-world exploits use complex Unicode obfuscation to bypass basic WAF signatures.
4. Why This is “The Deserialization Ghost”
Unlike traditional SQL injection or XSS, React2Shell happens before your application code even runs.
Bypassing Auth Layers
Because the Flight protocol is handled at the framework level (inside React’s internals), the malicious payload is deserialized before it reaches your middleware or authentication checks. If the framework processes the stream, the RCE is already triggered.
Target Surface Area
The vulnerability isn’t limited to apps that use “Server Actions.” Any application running a vulnerable version of React 19 that supports RSC is potentially at risk. This includes:
- Next.js (15.x and 16.x)
- React Router (in RSC mode)
- Waku
- Vite/Parcel RSC integrations
5. The Real-World Impact (2025-2026)
As of early 2026, the data regarding React2Shell’s impact is staggering.
Widespread Exploitation
Security firms like Wiz and Mandiant reported that 39% of cloud environments contained at least one vulnerable React instance within 48 hours of disclosure. Automated scanners quickly weaponized the bug, leading to:
- Cryptojacking: Massive deployment of XMRig miners across Vercel and AWS Lambda instances.
- Data Exfiltration: Attackers using the RCE to query cloud metadata endpoints (like
169.254.169.254) to steal IAM roles and database credentials. - Persistent Backdoors: The “SNOWLIGHT” and “COMPOOD” malware families were seen using React2Shell to establish permanent footholds in enterprise networks.
The Cloudflare Incident
In a notable “collateral damage” event, Cloudflare experienced a brief outage in December 2025. The cause? An emergency rollout of WAF mitigations designed to block malformed Flight payloads was so aggressive that it accidentally broke legitimate React traffic for thousands of sites.
6. Am I Vulnerable? (Checklist)
If you are running a React-based application built between late 2024 and late 2025, you are likely in the crosshairs.
| Package | Vulnerable Versions | Patched Versions |
|---|---|---|
| React | 19.0.0 – 19.2.0 | 19.0.1, 19.1.2, 19.2.1+ |
| Next.js | 15.0.0 – 16.0.6 | 15.1.0, 16.0.7+ |
| react-server-dom-webpack | < 19.0.1 | 19.0.1+ |
Warning: Canary and Experimental builds of React (specifically those after 14.3.0-canary.77) are also highly vulnerable.
7. Detection & Mitigation Strategies
Immediate Mitigation: The WAF Shield
If you cannot patch immediately, your first line of defense is a Web Application Firewall (WAF). You should block any POST requests that:
- Contain the
Next-Actionorrsc-action-idheaders. - Contain the string
$@followed by property-traversal markers like:__proto__or:constructor. - Have unusually complex
multipart/form-datastructures directed at RSC endpoints.
The Permanent Fix: Patching
Updating your dependencies is the only way to kill the “Ghost.”
# Update Next.js
npm install next@latest react@latest react-dom@latest
# Verify your lockfile for the following packages:
# react-server-dom-webpack
# react-server-dom-turbopack
The patch introduces strict hasOwnProperty checks and hardens the Flight decoder against object-prototype traversal.
Runtime Monitoring
Deploy tools like Falco or Sysdig to watch for suspicious process spawns from your Node.js runtime.
- Indicator of Compromise (IoC): node process spawning
sh,bash,curl, orwget. - Indicator of Compromise (IoC): Unexpected outbound connections to known C2 (Command & Control) IP addresses or mining pools.
8. Lessons for the Future of React Security
React2Shell is a wake-up call for the “Server-First” era of web development. As we move more logic back to the server through RSC and Server Actions, we are re-introducing old classes of vulnerabilities in new, more abstract ways.
Serialization is Never Safe: Any protocol that reassembles complex objects from client input is a massive attack vector.
Framework-Level Security: Developers rely on frameworks to be secure by default. When the framework itself is the vector, standard application-level security (like JWTs or CSRF tokens) may not be enough.
The “Log4j” Effect: Modern web apps are built on a deep stack of dependencies. A bug in a core sub-package like react-server-dom-webpack can compromise millions of downstream applications.
Conclusion
React2Shell (CVE-2025-55182) will be remembered as the moment the React community faced its first major infrastructure-level security crisis. By understanding the Flight protocol’s deserialization mechanics, you can better defend against this “ghost” and build more resilient applications.
Have you audited your node_modules today? The ghost of RSC might still be lurking in your 2025 deployments.