CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

CVE-2025-55182
CVSS 10.0|EPSS 96.00%

React2Shell: When Server Components Serve Shells (CVE-2025-55182)

Amit Schendel
Amit Schendel
Senior Security Researcher•December 3, 2025•5 min read
Active Exploitation
CISA KEV Listed

Executive Summary (TL;DR)

React Server Components (RSC) failed to properly validate module exports during the deserialization of client-to-server payloads. By crafting a specific multipart request, unauthenticated attackers can bypass checks and execute arbitrary system commands. This is actively exploited in the wild (React2Shell).

A critical Remote Code Execution (RCE) vulnerability in React Server Components (RSC) allows unauthenticated attackers to hijack the deserialization process of Server Actions, turning a standard web request into arbitrary code execution.

The Hook: A Bridge Too Far

React Server Components (RSC) were sold to us as the holy grail of frontend development: run your heavy logic on the server, send lightweight JSON to the client, and blur the lines between backend and frontend. It is a beautiful abstraction. But as security researchers know, every abstraction is just a place to hide a vulnerability.

At its core, RSC introduces a mechanism for the client to invoke functions on the server—effectively a proprietary Remote Procedure Call (RPC) protocol. The server needs to listen, decode the request, look up the function, and run it. CVE-2025-55182, affectionately dubbed React2Shell, is what happens when that lookup logic is too trusting.

This isn't just an XSS or a data leak. This is full unauthenticated Remote Code Execution. It turns your shiny Next.js or React app into a public terminal for anyone with curl and a malicious payload. The vulnerability exists in the foundational packages that handle this communication: react-server-dom-webpack, react-server-dom-parcel, and react-server-dom-turbopack.

The Flaw: Trusting the Map

The vulnerability lives in how React handles "Server References." When a client triggers a Server Action, it sends a multipart form request. One part of this request contains a map—metadata telling the server, "Hey, I want to run the function exported as updateProfile from module user-actions."

The server-side decoder, specifically inside decodeReplyFromBusboy, parses this stream. The fatal flaw was a classic case of Insecure Deserialization mixed with Prototype Pollution. The server would resolve the module ID provided by the client and then blindly access the property name requested by the client.

In the unpatched versions, the code didn't rigorously check if the requested export actually belonged to the module. It just tried to grab it. If an attacker requested a property inherited from Object.prototype (like __proto__ or constructor) or pointed the module ID to something internal (like the process global), the JavaScript engine happily obliged. By the time the server realized something was wrong, the payload had already corrupted the execution flow.

The Code: The One-Line Difference

Let's look at the "smoking gun" in the bundler configuration. The fix is embarrassingly simple, highlighting just how fragile dynamic property access can be in JavaScript.

Here is a simplified view of the vulnerable logic used to resolve a server reference:

// VULNERABLE LOGIC
function requireModule(moduleId, exportName) {
  const mod = __webpack_require__(moduleId);
  // If the attacker controls exportName, they can access
  // inherited properties or internal getters.
  return mod[exportName];
}

And here is the patch implemented by Meta. Notice the introduction of hasOwnProperty:

// PATCHED LOGIC
function requireModule(moduleId, exportName) {
  const mod = __webpack_require__(moduleId);
  // Verify the export actually exists on the module instance
  // and isn't something sneaky from the prototype chain.
  if (mod && mod.hasOwnProperty(exportName)) {
    return mod[exportName];
  }
  throw new Error('Export not found');
}

Additionally, the patch hardened decodeReplyFromBusboy in ReactFlightDOMServerNode.js. Previously, if an error occurred during stream processing, the server might leave the stream open or partially processed. The fix now wraps the resolution in a try...catch block and explicitly calls busboyStream.destroy(error), nuking the connection the moment malformed data is detected.

The Exploit: Crafting the Payload

Exploiting this requires understanding the RSC wire format. It's not standard JSON; it's a stream of tagged data. An attacker constructs a multipart/form-data request targeting a Server Action endpoint.

Step 1: The Setup The attacker sends a payload defining a "Server Reference." They manipulate the id (the module path) and the name (the export name).

POST /rsc-endpoint HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
 
------WebKitFormBoundary
Content-Disposition: form-data; name="1_metadata"
 
{"id":"./node_modules/.../vulnerable-module.js","name":"constructor","chunks":[]}
------WebKitFormBoundary--

Step 2: The Execution By setting the name to constructor or utilizing a gadget chain within the available modules on the server, the attacker can instantiate arbitrary objects. If they can point the module ID to a system library (if the bundler configuration allows internal module resolution, which often happens in misconfigured Webpack setups), they can invoke child_process.exec.

Even without direct internal module access, attackers have used this to pollute Object.prototype, causing the next legitimate server operation to execute a command payload injected into the prototype chain. This is exactly what the "Rondodox" botnet is doing—spraying these requests to turn servers into mining zombies.

The Impact: Why Panic?

This is a CVSS 10.0. That is not a score handed out lightly. It means:

  1. Network Accessible: Can be hit over the internet.
  2. Low Complexity: No race conditions or complex memory grooming needed.
  3. No Privileges Required: You don't need a login.
  4. No User Interaction: The admin doesn't need to click a link.

If you are running a modern React/Next.js stack with Server Actions enabled (which is the default in newer versions), you are likely vulnerable. The impact is total system compromise. Attackers can read environment variables (AWS keys, DB creds), delete data, or install persistent backdoors. CISA adding this to the KEV catalog confirms that ransomware groups are already using it to breach corporate networks.

The Fix: Stop the Bleeding

There is no configuration workaround that is safe enough. You must patch. The vulnerability is in the core logic of how React talks to the server.

Upgrade Paths:

  • React 19.2.x -> 19.2.1
  • React 19.1.x -> 19.1.2
  • React 19.0.x -> 19.0.1

After patching, check your logs. Look for 500 errors on Server Action endpoints involving multipart parsing errors—this could indicate failed exploit attempts. Also, consider adding WAF rules to block multipart requests containing suspicious keywords in the name field (like prototype, __proto__, or constructor), though this is a fragile defense compared to patching.

Official Patches

Meta / ReactOfficial React Security Release Announcement

Fix Analysis (1)

Technical Appendix

CVSS Score
10.0/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
EPSS Probability
96.00%
Top 1% most exploited
150,000
Estimated exposed hosts via Shodan

Affected Systems

React Server Components (RSC)Next.js (App Router)React Server DOM WebpackReact Server DOM ParcelReact Server DOM Turbopack

Affected Versions Detail

ProductAffected VersionsFixed Version
react-server-dom-webpack
Meta
19.0.0 - 19.0.019.0.1
react-server-dom-parcel
Meta
19.1.0 - 19.1.119.1.2
react-server-dom-turbopack
Meta
19.2.0 - 19.2.019.2.1
AttributeDetail
CVSS Score10.0 (Critical)
CWE IDCWE-502 (Insecure Deserialization)
VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Exploit StatusActive / Weaponized
KEV StatusListed (CISA KEV)
Attack VectorNetwork (RSC Protocol)

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1203Exploitation for Client Execution
Execution
T1059.007Command and Scripting Interpreter: JavaScript
Execution
CWE-502
Deserialization of Untrusted Data

The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.

Exploit Resources

Known Exploits & Detection

GitHubProof of concept demonstrating RCE via prototype pollution in RSC
NucleiDetection Template Available

Vulnerability Timeline

Vulnerability Timeline

Vendor Releases Patch
2024-12-03
Added to CISA KEV
2024-12-05
Public Exploitation Detected (Rondodox)
2024-12-06

References & Sources

  • [1]React Security Release: CVE-2025-55182
  • [2]CISA KEV Catalog

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.