On December 3, 2025, NIST published CVE-2025-55182 — soon nicknamed React2Shell — with a CVSS 3.1 base score of 10.0 — the maximum possible severity, network-exploitable with no authentication and no user interaction required. The flaw sits in react-server-dom-webpack, react-server-dom-turbopack, and react-server-dom-parcel, the packages that implement React Server Components' wire protocol, affecting versions 19.0.0, 19.1.0–19.1.1, and 19.2.0, and it cascades into Next.js 15.0.0 through 16.0.6 wherever the Node.js runtime is used. CISA added it to the Known Exploited Vulnerabilities catalog just two days later, on December 5, with a federal remediation deadline of December 12. Security researchers and vendors — Google Threat Intelligence Group, AWS, Microsoft, Rapid7, Datadog, and Wiz among them — tracked exploitation within days of disclosure under the nickname "React2Shell," with Google's threat intel team reporting campaigns ranging from opportunistic cryptomining to suspected espionage activity. The root cause is CWE-502, deserialization of untrusted data, in a code path that every RSC-enabled app exposes by design: the Server Function endpoint that turns a client action into a server-side call. This post breaks down how the bug works, why RSC's architecture made it possible, and what to do if you're running RSC in production today.
What actually made CVE-2025-55182 exploitable?
React Server Components ship a custom wire protocol that serializes React elements and Server Function call arguments into a compact stream sent over HTTP, then deserializes that stream back into live objects and function calls on the server. The vulnerability is that the deserializer trusted the structure of client-supplied payloads without strict schema validation before reconstructing objects and dispatching calls. An attacker could send a single crafted POST request to any Server Function endpoint — no login, no session, no prior interaction — and have the deserialization logic reconstruct attacker-controlled state that influenced server-side execution, ultimately running arbitrary JavaScript under the Node.js process. This is the same underlying bug class as classic Java and PHP object-deserialization RCEs, and Node's own history with unsafe eval-adjacent deserialization, just relocated into a framework-level, pre-authentication network path that ships on by default in any app using RSC's default configuration.
Why did this spread across so many frameworks at once?
Because react-server-dom-webpack, react-server-dom-turbopack, and react-server-dom-parcel are the shared low-level runtime that bundler-specific RSC integrations build on top of, patching React alone wasn't enough — every framework that wires a bundler to that runtime inherited the flaw. Next.js was the highest-profile downstream consumer, with the vulnerable code path present from 15.0.0 through 16.0.6 and in 15.6.0 canary builds, but any custom RSC integration built directly on those packages was equally exposed. This is the supply-chain reality of modern frontend frameworks: a single deserialization bug three layers below your application code can become a pre-auth RCE in production without a single line of your own code changing. Teams who believed "we didn't write that code, so it's not our risk" were the ones caught flat-footed when exploitation began within 48 hours of public disclosure.
How fast did exploitation actually happen after disclosure?
Exploitation activity was observed within roughly 48 hours of the December 3, 2025 public disclosure — fast enough that CISA's KEV addition and one-week remediation deadline reflected active, not theoretical, risk. AWS's security team documented China-nexus threat clusters weaponizing the bug rapidly, and Google's Threat Intelligence Group reported exploitation spanning opportunistic cybercrime actors deploying cryptominers up through more targeted intrusion activity. That compressed timeline is consistent with how CVSS 10.0 pre-auth RCEs in widely deployed web frameworks typically play out once a working proof-of-concept circulates: mass internet scanning for exposed Server Function endpoints starts almost immediately, and unpatched instances get compromised in an automated, unattended sweep rather than a targeted campaign.
What's the actual fix, and is a version bump enough?
The vendor fix is a version upgrade — React shipped 19.0.1, 19.1.2, and 19.2.1 to correct the unsafe deserialization logic in the affected react-server-dom-* packages, and Next.js released corresponding patched builds for its supported release lines. Upgrading is necessary but not sufficient on its own: because the vulnerable packages are transitive dependencies pulled in through your bundler tooling rather than direct entries in most package.json files, a straightforward npm audit or a shallow SCA scan can miss that your build actually resolves a vulnerable version several levels down the tree. Teams need to explicitly verify the resolved version of react-server-dom-webpack (or -turbopack / -parcel) in their lockfile, not just their top-level React version, since a pinned or cached lockfile can keep a vulnerable transitive copy in place even after bumping the direct react dependency.
How should teams running RSC in production defend against this class of bug going forward?
Beyond patching, defend the deserialization boundary itself: treat every Server Function endpoint as an untrusted, internet-facing input surface, and where your framework allows it, add request-size limits, schema validation ahead of the RSC runtime, and rate limiting on POST traffic to those routes. Because CVE-2025-55182 was a transitive-dependency issue hidden under bundler tooling, the practical detection gap is depth: dependency scanners that stop at 50–60 levels of resolution, which is typical for many SCA tools, can miss vulnerable react-server-dom-* packages resolved well past that point in a monorepo's dependency graph. Safeguard's deep dependency scanning resolves npm dependency trees to 100 levels specifically to catch cases like this, surfacing the exact transitive path — your app, through your framework, down to the vulnerable package — with reachability context rather than a bare version match. When a finding like this lands, Safeguard's zero-day pipeline rescoring flow also matters: an affected SBOM gets automatically rescored the moment a CVE like this is backfilled, Griffin AI opens a remediation pull request bumping the resolved version, and a policy gate can block any build still resolving an unpatched react-server-dom-* version before it ships.
What should a security team check right now?
If you landed here searching React2Shell CVE-2025-55182 remediation steps, start with the lockfile, not the changelog: confirm the exact resolved version of react-server-dom-webpack, react-server-dom-turbopack, and react-server-dom-parcel in every lockfile across your fleet, not just the top-level react and next versions, and upgrade to 19.0.1, 19.1.2, 19.2.1, or later, or the corresponding patched Next.js release. Check your WAF or edge logs for anomalous POST traffic to Server Function-style endpoints in the window following December 3, 2025, since exploitation began within days of disclosure per multiple vendor writeups. If you can't confirm a clean bill of health quickly across a large dependency graph, that's the exact gap deep, reachability-aware dependency scanning and automated remediation pipelines exist to close — this vulnerability class will recur in some other serialization boundary, and the defense that matters is depth of visibility, not just a single patch cycle.