devsamuelsantiago/rsc-module-loader-poc
GitHub: devsamuelsantiago/rsc-module-loader-poc
Stars: 0 | Forks: 0
### React Server Components Module Loader - Global Module.prototype._compile Patch Leading to RCE
A **security vulnerability** exists in the `react‑server‑dom‑webpack` and `react‑server‑dom‑unbundled` Node.js packages when using the `node‑register.js` module loader. The loader **globally patches `Module.prototype._compile`** to intercept modules containing `"use client"` and `"use server"` directives, without any per‑module validation, scope limitation, or context‑awareness. This global modification can be abused in certain deployment scenarios (e.g., multi‑tenant servers, plugin systems, or dynamic `require()` of user‑controlled paths) to achieve **arbitrary code execution within the process context**, leading to **RCE, data exfiltration, and cross‑tenant or supply‑chain impact**.
The vulnerability is **distinct from prior React Server Components‑related CVEs** (such as CVE‑2025‑55182 or CVE‑2026‑23869) because it stems from the **unsafe monkey‑patching of Node.js core module protocol** (`Module.prototype._compile`), not from deserialization or RSC protocol parsing bugs.
**Affected products / versions:**
- `react‑server‑dom‑webpack` (all versions using `node‑register.js`)
- `react‑server‑dom‑unbundled` (all versions using `node‑register.js`)
- Applications that `require('react‑server‑dom‑webpack/node-register')` or equivalent in a Node.js runtime (e.g., Next.js Server Components setups, custom RSC implementations).
**Impact:**
- **Remote Code Execution (RCE)** in the context of the Node.js process, if the attacker can control a module path or content loaded after the RSC loader is registered.
- **Cross‑tenant / cross‑user compromise** in multi‑tenant Node.js processes sharing plugins or modules.
- **Supply‑chain impact** if a malicious or compromised dependency is loaded after the loader is active.
- **Privilege escalation** and **data exfiltration** via access to `process.env`, `global`, module cache, and filesystem.
This issue is **critical** in environments where:
- multiple tenants or users share a single Node.js process,
- or where plugins / modules are loaded from user‑controlled paths.
**Exploitation conditions:**
- The RSC loader must be registered (e.g., `require('react‑server‑dom‑webpack/node-register');`).
- The attacker must be able to:
- Inject a malicious module into the filesystem / module resolution path, **or**
- Control a path passed to `require()` (e.g., via HTTP query, plugin directory, or dynamic module loading).
**Proof of Concept (PoC) summary:**
A minimal PoC demonstrates that attacker‑controlled code is executed when the patched `_compile` processes a module containing `"use server"`:
1. Register the loader: `require('react‑server‑dom‑webpack/node‑register');`
2. Create a malicious module `./plugins/evil.js` containing `"use server"` and arbitrary code (e.g., setting `global.__ATTACKER_PAYLOAD__`).
3. `require('./plugins/evil.js')` triggers the patched `_compile`, executing the attacker code in the global scope.
Running the PoC confirms that arbitrary code is executed and visible via `global` inspection, proving RCE in the process context.