PatchDay Alert
Analysis · 5 min read · 1,056 words By The Field Notes Desk · Field Notes

React2Shell turned every Next.js App Router deployment into a pre-auth RCE target

Lachlan Davidson reported CVE-2025-55182 to Meta on a Friday. By the following Thursday, ransomware groups were deploying payloads within one minute of initial access. A 200-byte POST, CVSS 10, 137,000 exposed instances, and most developers never knew their frontend had server-side attack surface.

React2Shell turned every Next.js App Router deployment into a pre-auth RCE target

Ransomware group Weaxor deployed ransomware within one minute of initial access on December 5. Not one minute after reconnaissance. Not one minute after privilege escalation. One minute after the first POST request hit the server. That’s the operational reality of CVE-2025-55182: a 200-byte payload, no credentials, no user interaction, CVSS 10.0, and the target endpoint exists by default in every Next.js App Router project created since version 13.4.

The vulnerability, named React2Shell, is a deserialization flaw in React’s Flight protocol. It is the first critical RCE in React’s history, and it hit an ecosystem where most developers had never modeled their application as having server-side attack surface at all. Every project generated with create-next-app ships with App Router enabled. The Flight endpoint is implicitly active. Nobody opted in. Everybody was exposed.

How a frontend framework became a server-side RCE

React Server Components (RSC) run on the server and send a serialized UI description to the browser via the “Flight” protocol. React Server Functions (formerly Server Actions) accept POST requests from the client, deserialize the payload on the server, and execute the function with full Node.js privileges: filesystem access, database connections, environment variables, network access.

The Flight deserializer was built assuming payloads come from trusted React clients. CVE-2025-55182 breaks that assumption. An attacker sends a crafted multipart/form-data POST containing a fake Chunk object with a custom then method that hijacks promise resolution inside the Flight decoder. The server treats the attacker’s payload as trusted internal state and executes the embedded code. From the attacker’s perspective, the RSC endpoint is a shell.

Applications that define no explicit Server Functions are still vulnerable if RSC is enabled, because the Flight endpoint is implicitly active in frameworks like Next.js App Router. React became a server runtime but didn’t inherit any server-hardening assumptions. Standard WAFs could not inspect the proprietary Flight wire format. The trust boundary was invisible to both the developers writing the code and the security teams reviewing it.

The scope

React is used by approximately 40% of web developers. Next.js runs on 200,000+ active domains. Shadowserver identified 137,200+ internet-exposed IPs running vulnerable code as of December 11, 2025. Wiz reported 39% of analyzed cloud environments contained vulnerable versions.

What is affected:

  • Next.js App Router (15.0.0-15.5.7, 16.0.0-16.0.6, canary builds from 14.3.0-canary.77)
  • React server packages (react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack) versions 19.0.0 through 19.2.0
  • Other RSC frameworks: React Router with RSC, Waku, @parcel/rsc, @vitejs/plugin-rsc, Redwood SDK

What is not affected:

  • Client-side React (SPAs, create-react-app, Vite without RSC)
  • Next.js Pages Router
  • React 18 and older
  • Next.js Edge Runtime

Self-hosted deployments on AWS, GCP, Azure, and Kubernetes were hit hardest. Vercel deployed WAF rules at the edge before public disclosure, providing partial coverage for hosted apps, but explicitly stated this was not a substitute for patching.

The exploitation timeline

Lachlan Davidson reported the vulnerability to Meta Bug Bounty on November 29, 2025 (a Saturday). Meta confirmed November 30. Patches published to npm on December 3. Four-day turnaround from report to patch. That part of the story went well.

Then it went badly. Exploitation began within hours of disclosure. China-nexus groups Earth Lamia and Jackpot Panda were among the first, targeting cloud infrastructure for credential harvesting and lateral movement. Weaxor deployed ransomware on December 5, same day CISA added it to the KEV catalog with a 7-day deadline. By December 10, Kaspersky was recording 35,000+ daily exploitation attempts. GreyNoise confirmed opportunistic mass-scanning was underway within days.

Observed payloads included coin miners, Mirai loader, VShell RAT, Cobalt Strike, and credential harvesting tools targeting cloud metadata endpoints. By April 2026, 766 Next.js hosts had been confirmed breached with credential theft.

What you need to do

Check if you’re vulnerable. Run npx fix-react2shell-next --dry-run in your project root. It scans all package.json files across workspaces and reports vulnerable versions without changing anything. Alternatively, check npm list react-server-dom-webpack for versions below the patched releases.

Patch. React server packages need to be at 19.0.1, 19.1.2, or 19.2.1 depending on your minor version. For Next.js, run npx fix-react2shell-next --fix, which bumps all affected dependencies and refreshes your lockfile across npm, yarn, pnpm, or bun workspaces. Then rebuild and redeploy.

The rebuild-and-redeploy step is where this gets operationally heavy. The fix lives in node_modules, so every deployment needs a fresh build. For teams running microservice architectures with dozens of Next.js services, Imperva documented sustained attack campaign activity weeks after patch availability because patching deeply nested dependencies across distributed fleets takes time. One command per repo; multiply by the fleet.

If you’re on Vercel: The platform deployed WAF rules automatically, but Vercel’s own guidance is clear: “Do not rely on the WAF for full protection. Immediate upgrades to a patched version are required.”

If you can’t patch immediately: Block or restrict access to RSC/Server Function endpoints at your WAF or reverse proxy. The exploit targets POST requests with malformed Flight payloads. Cloudflare, Palo Alto (signatures 96779, 96780, 96787), and Azure WAF all published specific rules for React2Shell. These are compensating controls, not fixes.

Check for compromise. Look for Node.js processes spawning bash, curl, wget, or nc. Check /tmp/ for unexpected binaries or shell scripts. Look for outbound connections to cloud metadata endpoints (169.254.169.254 for AWS IMDS). Microsoft Defender has a specific signature: Trojan:JS/CVE-2025-55182.A. If you find indicators, assume your environment variables were exfiltrated. Rotate all application secrets, database credentials, and API keys after patching.

The operational lesson

React2Shell happened because React added server-side execution to what was historically a client-side rendering library, without auditing the deserialization trust model. The framework defaulted developers into server-side attack surface without requiring them to understand that’s what they were getting. If your development team adopted App Router because it was the Next.js default, your application has server-side attack surface that nobody on the team explicitly decided to create. The RSC endpoint exists, is publicly reachable, and was exploitable with a 200-byte request.

The patch is available. The tooling is good. npx fix-react2shell-next --fix is one command. The hard part is the fleet: every service, every deployment, every environment needs a rebuild. PatchDay Alert tracks CISA KEV additions across the stack. This one hit the frontend, and that made it unusual. But the remediation is the same as any critical infrastructure vulnerability: patch, verify, rotate secrets, and check for signs of compromise before assuming you’re clean.

Sources

Share

Related field notes

One email, every weekday morning.

You're in. Check your inbox.

Get the digest

Free. Weekday mornings. Plain English CVE triage.

Check your inbox to confirm.