React2Shell: Anatomy of a 10.0
On December 3, 2025, the React team published a security advisory that stopped the JavaScript ecosystem cold. CVE-2025-55182 — a CVSS 10.0 unauthenticated remote code execution vulnerability in React Server Components — was being actively exploited within hours of disclosure.
CVSS: 10.0 (Critical)
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Affected: react-server-dom-webpack, react-server-dom-turbopack, react-server-dom-parcel
Fixed: React 19.1.0
A single crafted POST request. Full server takeover. No authentication required.
They called it React2Shell.
React Server Components and the Flight Protocol
To understand how this happened, you need to understand React Server Components (RSC). Introduced with React 18 and matured in React 19, RSCs let you render components on the server and stream them to the client. The wire protocol that makes this work is called Flight.
Flight serializes the component tree — props, references, and Server Function arguments — into a binary-ish format that gets sent between client and server. When a user interacts with a form or calls a Server Action, the client sends a Flight-encoded payload back to the server, which deserializes it and executes the referenced function.
Client → Server: POST /_rsc (Flight-encoded payload)
Server: Deserialize → Resolve references → Execute Server Function
The problem? The deserialization was too powerful.
The Flaw
Security researcher Lachlan Davidson discovered that the Flight protocol’s deserialization logic allowed attacker-controlled inputs to traverse the prototype chain and access the Function constructor. This meant an attacker could construct arbitrary JavaScript functions on the server side through nothing more than a crafted HTTP request.
HACK
The exploit works through prototype chain traversal during deserialization. The server processes RSC payloads without sufficient validation, and under specific conditions, a malformed payload causes the server to reach the Function constructor — enabling arbitrary code execution.
The attack surface was enormous. Any application using React Server Components with Server Functions was vulnerable. But it was even worse than that — Rapid7 confirmed that applications without explicitly defined Server Functions were still vulnerable if they used RSC at all. Standard Next.js production builds include RSC endpoints that can be reached without special routing or configuration.
Wiz reported that 39% of cloud environments contained instances of Next.js or React in versions vulnerable to CVE-2025-55182.
The Exploit Chain
The exploitation is devastatingly simple:
- Attacker identifies a target running React 19.x with Server Components (trivially fingerprintable)
- Attacker sends a crafted POST request to any RSC endpoint
- The Flight deserializer processes the malicious payload
- Prototype chain traversal reaches the Function constructor
- Attacker-supplied code executes in the server’s Node.js process
- Full RCE achieved — reverse shell, data exfiltration, lateral movement
The exploit had a near-100% success rate against vulnerable targets. No memory corruption, no race conditions, no unreliable heap spraying — just clean, deterministic deserialization-to-execution.
WARN
We are not publishing exploit code. The vulnerability is well-documented by Wiz, Rapid7, and others. If you need to test your systems, use the scanner at
github.com/Security-Phoenix-demo/react2shell-scanner.
In the Wild
The timeline was brutal:
| Date | Event |
|---|---|
| Nov 29, 2025 | Lachlan Davidson discovers the vulnerability, reports to React team |
| Nov 30 | Meta security confirms the flaw |
| Dec 1 | Fix created, coordinated rollout to hosting providers begins |
| Dec 3 | Fix published to npm, CVE-2025-55182 publicly disclosed |
| Dec 4 | Davidson publishes PoC on GitHub |
| Dec 5 | Exploitation detected in the wild by Amazon, GreyNoise, Rapid7 |
Within hours of disclosure, multiple China-nexus threat groups — including Earth Lamia and Jackpot Panda — were actively exploiting the vulnerability. Amazon’s threat intelligence team observed active exploitation attempts almost immediately.
DPRK’s UNC5342 followed quickly, deploying React2Shell as an initial access vector for their EtherRAT campaign (see Article #3 in this issue).
By late December, GreyNoise had recorded over 8.1 million attack sessions, with daily volumes stabilizing between 300,000-400,000 attempts. Their observation grid detected 8,163 unique source IPs across 1,071 ASNs spanning 101 countries.
BleepingComputer reported that attackers had breached over 30 organizations, with 77,000 internet-exposed IP addresses remaining vulnerable.
Post-exploitation activity followed a familiar playbook: reconnaissance commands confirming RCE (PowerShell math operations as a canary), then Cobalt Strike beacon deployment for persistent access.
Next.js: A Companion CVE
The vulnerability also received a Next.js-specific tracking as CVE-2025-66478, though this was later rejected as a duplicate — the root cause was in React’s Flight deserializer, not in Next.js itself. Vercel published a one-command fix: npx fix-react2shell-next to automatically bump affected dependencies.
Detection and Mitigation
Immediate actions:
# Check if you're running vulnerable React versions
npm ls react-server-dom-webpack react-server-dom-turbopack react-server-dom-parcel
# Fix Next.js applications
npx fix-react2shell-next
# Or manually update React to 19.1.0+
npm install react@latest react-dom@latest
WAF signatures to detect exploitation attempts should look for:
- Malformed POST requests to RSC endpoints (
/_rsc, Server Action paths) - Flight protocol payloads containing prototype chain traversal patterns
- Unusual
Content-Typeheaders on Server Function endpoints
Network indicators:
- POST requests to
/_rscendpoints from external sources - Outbound connections to known Cobalt Strike infrastructure post-exploitation
- PowerShell execution from Node.js processes
The Bigger Picture
React2Shell wasn’t just another CVE. It was a structural failure.
The Flight protocol was designed for performance, not security. Deserialization was trusted implicitly. The attack surface was enabled by default. And when the vulnerability dropped, the entire JavaScript ecosystem — from startups to Fortune 500 — was exposed simultaneously.
INFO
Comparisons to Log4Shell (CVE-2021-44228) are apt. Both were unauthenticated RCE in ubiquitous software. Both exploited deserialization trust boundaries. Both had near-instant exploitation by nation-state actors. The key difference: React2Shell had even broader reach because every Next.js App Router deployment was a target.
The fix was two lines of code. The damage was measured in months.
React2Shell is a reminder that “move fast” culture has consequences. When your serialization protocol becomes the most deployed attack surface on the internet, it better be hardened like one.
Patch your servers. Then read Article #3 to see what DPRK did with the access.
-- fl1ght