## https://sploitus.com/exploit?id=881F7FBF-53EE-59AF-AB11-925EE7531A9D
# CVE-2025-55182 and CVE-2025-66478
## Technical Analysis of Argument Injection in React Server Components and Next.js Server Actions
**Author**: Santiago Habib
**Date**: December 2025
https://x.com/kalirsec
---
## 0. Executive Summary
CVE-2025-55182 (React) and CVE-2025-66478 (Next.js) describe a critical vulnerability in the Flight protocol used by React Server Components (RSC). Due to a lack of type validation during the deserialization of arguments passed to Server Actions, an attacker can supply specially crafted "array-like" objects that are mistakenly interpreted as legitimate argument lists.
If a developer uses these arguments without validation inside sensitive operations โ such as system commands, SQL queries, or file operations โ the issue can escalate to **Remote Code Execution (RCE)**. The vulnerability does not execute code on its own; it enables arbitrary argument injection into server-side functions.
This document provides a detailed technical analysis of the flaw, a description of the vulnerable code path, evidence of the attack vector, exploitation requirements, patch information, and mitigation recommendations.
---
## 1. Background
### 1.1 React Server Components and the Flight Protocol
React Server Components (RSC) implement a model where the server serializes components, function references, and arguments through the "Flight" protocol. Next.js relies on this mechanism to implement Server Actions โ functions that can be invoked directly from client components.
The Flight protocol serializes various kinds of data, including references to server actions and their bound arguments.
### 1.2 Server Actions and Argument Pre-Binding (`.bind()`)
The `.bind()` mechanism allows Server Actions to receive predefined arguments before they run. Example:
```javascript
const boundAction = myAction.bind(null, userId);
```
The `userId` is serialized in the RSC payload under the structure:
```
$ACTION_REF_1={"id":"","bound":{"value":[โฆ]}}
```
On the server, these values are deserialized and reassembled before invoking the action.
---
## 2. Vulnerability Description
### 2.1 Root Cause
The implementation of React Server DOM takes `bound.value` without validating its type. It assumes it is an array, but it can actually be any object. The server then executes:
```javascript
fn.bind.apply(fn, [null].concat(boundArgs));
```
JavaScript treats any object with numeric keys and a `length` property as "array-like" when passed to `apply()`. This allows an attacker to inject arbitrary arguments into developer-defined Server Actions.
### 2.2 Vulnerable Code (Next.js 15.0.4)
Real vulnerable code snippet:
```javascript
if (bound)
bound = Promise.all([bound, id]).then(function (_ref) {
_ref = _ref[0]; // Controlled by the client
var fn = requireModule(serverReference);
return fn.bind.apply(fn, [null].concat(_ref));
});
```
Because there is no check ensuring `_ref` is a real array, an attacker can send:
```json
{"0": "whoami", "length": 1}
```
This is interpreted as:
```javascript
fn.bind(null, "whoami");
```
Which replaces the intended argument for the Server Action.
---
## 3. Attack Vector
### 3.1 Attacker Controls `bound.value`
The attacker sends a malicious RSC payload where `bound.value` is an object. Due to missing validation, the server processes it as an array.
### 3.2 Attacker Controls the Server Action Arguments
If a developer uses these bound arguments inside sensitive operations โ for example:
```javascript
await exec(`ls /uploads/${userId}`);
```
โ and `userId` comes from `.bind()`, the attacker can inject arbitrary content.
### 3.3 Not an Automatic RCE
**The vulnerability only enables arbitrary argument injection. It becomes RCE only when developer code uses these arguments unsafely.**
---
## 4. Exploitability Analysis
### 4.1 Validation of the Vulnerable Code
A comparison of:
- Next.js 15.0.4 (vulnerable)
- Next.js 15.0.5 (patched)
confirms:
- โ The vulnerable code path existed.
- โ The patch introduces `Array.isArray()`.
- โ The vulnerable version allows non-arrays to reach `apply()`.
### 4.2 Controlled Testing Environment
To validate the attack vector, a clean and isolated environment was used:
- Next.js 15.0.4
- React 19.0.0
- No additional dependencies
- No custom middleware
A proof-of-concept Server Action was created intentionally to test the vector:
```typescript
'use server'
import { exec } from 'child_process'
import { promisify } from 'util'
const execPromise = promisify(exec)
export async function testAction(...args: any[]) {
const cmd = args[0]?.["0"] || args[0]?.command
if (cmd && typeof cmd === 'string') {
const { stdout } = await execPromise(cmd)
return { output: stdout }
}
}
```
**Important**: This function does not represent real-world production logic; it is strictly for validating the attack vector.
### 4.3 Validation Findings
The controlled experiment confirmed:
- โ Objects can be injected instead of arrays.
- โ `apply()` interprets the object as array-like.
- โ The vulnerability occurs before developer-defined code runs.
- โ Version 15.0.5 correctly blocks the attack path.
### 4.4 Real-World Exploitability
Whether the issue becomes exploitable depends entirely on application code. It becomes exploitable only if:
1. Server Actions use `.bind()`.
2. The bound arguments are not validated.
3. Those arguments are used in sensitive operations.
**Real-world vulnerable pattern:**
```typescript
// Client
const processFile = processUserFile.bind(null, currentUserId);
// Server
export async function processUserFile(userId: string, formData: FormData) {
const filename = formData.get('filename');
await exec(`convert /uploads/${userId}/${filename} output.jpg`);
}
```
If `userId` is not validated, an attacker can inject:
```json
{"0": "../../../etc/passwd; cat /etc/passwd #"}
```
---
## 5. Detailed Vulnerable Code Path
The full vulnerable chain in 15.0.4:
1. Client sends a payload containing `bound.value`.
2. Next.js deserializes the RSC payload.
3. `bound.value` is passed into `loadServerReference$1`.
4. The server executes `fn.bind.apply(fn, [null].concat(bound.value))`.
5. If `bound.value` is array-like, its values become real arguments.
6. Developer code receives these attacker-controlled arguments.
---
## 6. The Patch (Next.js 15.0.5 / React 19.0.1)
The patch introduces explicit validation:
```javascript
promiseValue = Array.isArray(promiseValue)
? promiseValue.slice(0)
: [];
```
This ensures:
- โ Only real arrays are accepted.
- โ Malicious objects result in an empty array.
- โ The argument injection vector is fully blocked.
---
## 7. Impact
### 7.1 Severity
**CVSS: 9.8 โ Critical**
Because:
- Remote exploitation is possible.
- No authentication is required.
- It enables influence over server-side logic.
### 7.2 Clarifying the Practical Impact
**The vulnerability itself:**
- Does not run commands.
- Does not write files.
- Does not execute code.
**But it does allow attackers to modify arguments passed to critical functions.** In many real applications, this is enough to turn the issue into RCE.
---
## 8. Detection
Native detection is difficult because Next.js does not log RSC payloads.
**Possible detection strategies:**
- Manual logging inside Server Actions.
- Request inspection for patterns like `"0":` or `"length":`.
- Traffic analysis of the Flight protocol.
---
## 9. Mitigation
**Immediate recommendation:**
```bash
npm install next@15.0.5
npm install react@19.0.1 react-dom@19.0.1
```
**Additional best practices:**
- Validate all bound arguments.
- Avoid using bound values inside shell commands.
- Prefer safe filesystem APIs.
- Use parameterized SQL queries.
- Apply rate limiting.
---
## 10. Conclusion
The vulnerability stems from assuming that `bound.value` is always an array. This assumption allows attackers to inject objects treated as arrays, modifying the real arguments passed into developer-defined Server Actions.
**The issue is not an automatic RCE.** It becomes RCE only when developer code uses these bound arguments unsafely inside sensitive operations. The attack vector is real and reproducible in controlled environments, and the patch fully addresses the issue.
---
## 11. References
- [Next.js Security Advisory](https://github.com/vercel/next.js/security/advisories/GHSA-9qr9-h5gf-34mp)
- [NVD - CVE-2025-66478](https://nvd.nist.gov/vuln/detail/CVE-2025-66478)
- [NVD - CVE-2025-55182](https://nvd.nist.gov/vuln/detail/CVE-2025-55182)
- [Wiz Security Analysis](https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182)
- [Aikido Security Blog](https://www.aikido.dev/blog/react-nextjs-cve-2025-55182-rce)
- [The Hacker News Article](https://thehackernews.com/2025/12/critical-rsc-bugs-in-react-and-nextjs.html)
- [React GitHub Repository](https://github.com/facebook/react)
---
**Document Version**: 3.0 (Final - English)
**License**: This document may be freely shared for educational and security purposes, with attribution to the author.