If you work in web engineering, the transition into 2026 hasn’t been defined by new features, but by a single, terrifying realization: The boundary between your client and server is broken.
In December, "React2Shell" (CVE-2025-55182) exposed a critical RCE in React Server Components. Barely after teams patched, two more high-severity exploits emerged in the same subsystem. This is the definitive technical post-mortem.
The "React2Shell" RCE (CVE-2025-55182)
To understand why this vulnerability (CVSS 10.0) was so devastating, we first have to understand the machinery it destroyed, the React Flight Protocol.
For years, the mental model for React developers was simple: React renders UI in the browser, and an API (REST/GraphQL) fetches data. The server and client were distinct worlds, separated by a clear network boundary.
React Server Components (RSC) erased that boundary.

In the RSC world, the server doesn't send HTML to the client. It streams a proprietary serialization format called "Flight." This stream contains descriptions of UI components, serialized data, and crucially Promises that resolve to data.
How React2Shell Works
React2Shell was not standard SQL injection or XSS. It was logic abuse targeting a deserializer. Attackers crafted HTTP POST requests with specific "Flight" payloads. These binary-like streams mimicked valid component trees while hiding a "Thenable" Object, or fake Promise.
- Injection: Attacker sends serialized object containing malicious
__proto__keys. - Deserialization: Server parses stream and tries resolving fake Promise.
- Prototype Pollution: Lack of sanitization lets
__proto__overwriteObject.prototypeon running Node.js process. - Gadget Chain: Modified prototype triggers internal calls targeting
Functionconstructor.
Accessing Function constructor means game over. Arbitrary strings like require('child_process').exec(...) compile and execute immediately.
How Next.js was Affected
Because Next.js App Router enables RSC by default, every Next.js application (versions 15.x, 16.x, and canary builds) was vulnerable out of the box. You didn't need to write a buggy Server Action to be hacked. You didn't even need to use Server Components explicitly. If your application booted up react-server-dom-webpack, it was listening for these Flight payloads.

Credits: Next.js for the image
The DevOps Nightmare
For DevOps engineers, "React2Shell" was a worst-case scenario.
- WAF Blindness: Standard Web Application Firewalls (WAFs) are trained to look for SQL injection (
' OR 1=1) or script tags (<script>). They were not trained to inspect the proprietary text format of React Flight. The malicious payloads passed right through Cloudflare and AWS WAF rules initially. - Supply Chain Hell: The vulnerability wasn't in user code; it was deep in
node_modules. You couldn't just "fix the code." You had to wait for Vercel and the React team to release patched binaries, then rebuild and redeploy every single microservice.
The Aftershocks (DoS and Leaks)
Just as engineering teams were recovering from the RCE panic, the security community found more cracks in the foundation. On December 11, 2025, the React team issued a new advisory for three additional CVEs.
While these aren't RCEs, they are operationally devastating and highlight the fragility of the current serialization implementation.
1. Denial of Service (CVE-2025-55184)
Severity: High (7.5/10)
This vulnerability allows attackers to "freeze" infrastructure with a single request.
Mechanism: Flight protocol allows data chunks to reference other chunks. Researchers discovered they could create circular dependencies in payloads.
- Chunk A references Chunk B.
- Chunk B references Chunk A.
When the React deserializer attempts to resolve this structure, it enters an infinite synchronous loop.

The Impact on Infrastructure: Because Node.js is single-threaded, this infinite loop blocks the entire Event Loop.
- CPU Spike: The CPU immediately jumps to 100%.
- Request Drops: The server stops responding to all other users. Health checks fail.
- Cluster Destabilization: In Kubernetes, the liveness probe might fail, causing the pod to restart. But if the attacker sends a stream of these requests, they can put the entire cluster into a "CrashLoopBackOff" state, effectively taking down the application.
Note: The initial fix for this was incomplete, leading to CVE-2025-67779 (the "fix for the fix"), which forced DevOps teams to patch their systems a third time in two weeks.
2. Source Code Leak (CVE-2025-55183)
Severity: Medium (5.3/10)
Arguably most embarrassing vulnerability for React ecosystem. It allows attackers to trick servers into sending source code back to clients.
Mechanism:
Exploit relies on JavaScript string coercion. If Server Action returns object implicitly calling .toString() on a function within server runtime, default V8 behavior returns function source code.
"Secrets" Risk:
Developers often assume code inside use server files is private. They might write:
// DO NOT DO THIS
const STRIPE_KEY = "sk_live_12345";
export async function purchase() { ... }
Under normal circumstances, STRIPE_KEY stays on the server. But with CVE-2025-55183, an attacker can manipulate the serialization of the return value to dump the scope of the function, potentially revealing hardcoded API keys, internal comments, and database schema details.
Immediate Action Plan
If you are running Next.js App Router (v13.3+) or React 19, you must execute the following plan immediately:
- The "Immediate" Update: Do not trust semantic versioning ranges. Pin your versions to the releases that explicitly fix all discussed CVEs.
npm install [email protected] [email protected] [email protected]
# Verify deeply nested dependencies
npm list react-server-dom-webpack
Ensure react-server-dom-webpack is at least version 19.0.2.
-
Implement Rate Limiting: The DoS exploit is cheap for attackers. You must implement aggressive rate limiting on all routes, especially
POSTrequests, at the infrastructure level (Nginx, Cloudflare, AWS WAF). -
Audit for Secrets: Assume your server code can be leaked. Run a scan of your
app/directory. If you find a single API key, hardcoded password, or internal IP address in a.tsor.jsfile, move it to an environment variable immediately.
Conclusion
React Server Components are a powerful evolution of the web, but "React2Shell" has proven that this power comes with a terrifying new attack surface. The Flight protocol is complex, and as we have seen, complexity is the enemy of security.
Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!

