Two new vulnerabilities in React and Next.js, have exposed a critical weakness in the React Server Components’ (RSC) “Flight” protocol. These vulnerabilities, known as CVE-2025-55182 and its corresponding vulnerability in Next is CVE-2025-66478 that impacts Next web deployments. These vulnerabilities have the CVSS score of 10 and it enables hackers to run a script on a server through a single unauthenticated HTTP request.
These are critical vulnerabilities that affect core RSC packages as well as major frameworks that rely on them, including Next.js, React Router’s RSC preview, Redwood SDK, Waku, and RSC plugins for Vite and Parcel.
In this blog, we’ll explore how to deal with these vulnerabilities, how they work, and how you can defend your React and Next deployments.
Let’s get started!
Understanding CVE-2025-55182
CVE-2025-55182 is an unauthenticated remote code execution (RCE) vulnerability in React’s Flight Protocol implementation. The vulnerability exists in the ReactFlightReplyServer.js file, where user-supplied data is deserialized without proper validation.
CVE-2025-55182 affects the react-server package within React Server Components. Additionally, both vulnerabilities emerge from insecure deserialization of RSC payloads. When the server receives a specially crafted payload, the RSC handler fails to properly validate it that allows attacker-controlled data to control server-side execution.
As a result, the JavaScript on the server is executed without authentication or prior access. What is even more dangerous is that they affect applications even if they do not define Server Functions, because the RSC integration layer itself invokes the vulnerable logic.
Affected Versions
React Versions:
The following React versions are vulnerable and should be upgraded immediately:Note: All affected releases are resolved by upgrading to React 19.0.1 or later.

Next.js Versions:
This vulnerability also impacts applications using Next.js, depending on the framework branch:

CVE-2025-55182: Myth vs Reality

Lab Set Up (Test Environment)
Let’s set up the lab environment.
mkdir ~/react2shell-lab && cd ~/react2shell-lab
npx [email protected] vulnerable-app –yes
cd vulnerable-app
npm ls next react react-dom

Create Server Action
app/actions.ts
```typescript
'use server';
export async function handleSubmit(data: ): Promise<void> {
console.log('Received:', data.get('input'));
}
```
And for the page
app/page.tsx
```typescript
import { handleSubmit } from './actions';
export default function Page() {
return (
<form action={handleSubmit}>
<input name="input" />
<button type="submit">Send</button>
</form>
);
}
```
Now, Build and Run
npm run build
npm run start

The application will be available at `http://localhost:3000

The Proof of Concept (PoC)
We are going to use this https://github.com/msanft/CVE-2025-55182 as the PoC. As we see in the image below, it shows the execution of the id command in the system.

Payload Structure Execution Flow
- The server receives a multipart request.
- Field 1 (“$@0”) exposes the raw chunk from Field 0.
- $1:__proto__:then traverses the prototype chain.
- $1:constructor:constructor resolves to the Function constructor.
- Function(_prefix) executes child_process`.`execSync(‘id’).
- The command output is returned in the error digest along with the execution result.
Now, before discussing the Prototype pollution, let’s first understand the RCS components. Understanding how RSC works is critical before examining prototype pollution or remote code execution paths.
What is Prototype Pollution?
In JavaScript language, a prototype has a hidden link to another object called its prototype. When you access a property, JavaScript first checks the object itself, and then walks up the prototype chain.
```javascript
const user = { name: "admin" };
// Property exists on object
user.name // "admin"
// Property doesn't exist - JavaScript checks prototype chain
user.toString() // "[object Object]" (found on Object.prototype)
// Direct prototype access
user.__proto__ // Object.prototype
```
Why is “ __proto__” Property Dangerous?
The __proto__ property provides direct access to an object’s prototype. While untrusted input is deserialized without proper safeguards, allowing access to __proto__ enables attackers to traverse or manipulate the prototype chain.
// Normal property access
obj["name"]; // Returns obj.name
// Prototype traversal — dangerous
obj["__proto__"]; // Returns Object.prototype
Reaching the Function Constructor
Every function in JavaScript has a constructor property. By chaining constructor accesses, an attacker can eventually reach the Function constructor:
const obj = {};
obj.constructor // Object (function)
obj.constructor.constructor // Function (constructor of all functions)
The Function constructor can then be used to create and execute arbitrary code:

Understanding React Server Component
React Server Components (RSC) are a rendering architecture introduced in React 18 that allow components to execute exclusively on the server. Unlike traditional Server-Side Rendering (SSR), RSC components never hydrate on the client, and their JavaScript is not included in the client bundle.
In addition, React Server Components change long-standing assumptions about where code runs and where data is trusted. They shift part of the application’s execution model into a server-controlled environment that still consumes client-influenced input. That shift is precisely what makes deserialization paths, reference resolution, and prototype handling security-critical in modern React applications.
The Flight Protocol
The Flight protocol is React’s custom serialization format built specifically for React Server Components. It handles the streaming transfer of component trees, data, and references between the server and the client.
What It Does
Flight solves a core challenge: transmitting a React component tree, including props, nested components, and references, over the network. Traditional JSON falls short because it cannot represent React elements, functions, promises, or circular references. Flight is designed to handle all of these safely and efficiently.
To do this, the protocol serializes React’s virtual DOM into a streamable format that the client can progressively reconstruct. This enables features like streaming rendering, where the browser can begin rendering before the entire response is complete.
Message Format
Each Flight message is sent as a single row consisting of three parts: an ID, a type indicator, and a data payload, followed by a newline.
The ID is a hexadecimal identifier for the chunk. Other chunks can reference it, allowing the component tree to be reassembled. Values such as 0, 1, a, or ff represent different parts of the tree. The type indicator is a single character that defines how the payload should be interpreted:

The data payload is typically JSON containing component props, text content, nested references, or other serialized values.
To explain it lucidly, you can see the graphics:

Attackers actively look for React Server Components as they often create the entry point. These components are rendered on the server and streamed to clients through Server Actions, which introduces a server-side data processing surface.
Now, the Flight protocol handles serialization and deserialization of this data. It uses $ references to resolve object paths across streamed chunks. The flaw is that these paths are not validated. The deserializer follows whatever path it is given.
Because there is no path validation, an attacker can supply special paths such as __proto__. This allows traversal out of the intended object and into Object.prototype, eventually reaching the Function constructor.
Code Execution occurs through thenable injection. The attacker poisons the .then property on the prototype. When the deserializer tries to resolve what looks like a Promise, it calls.then(), executing the attacker’s code instead.
So where exactly is the bug in the code, and how it can be fixed. The next sections answers this question:
The Patch Diff
Vulnerable Code (Before Patch):
function getOutlinedModel(response, reference, parentObject, key, map) {
const path = reference.split(':');
const id = parseInt(path[0], 16);
const chunk = getChunk(response, id);
let value = chunk.value;
// VULNERABLE: No validation when traversing properties
for (let i = 1; i < path.length; i++) {
value = value[path[i]]; // Attacker can access __proto__
}
return map(response, value);
}
Patched Code (After Fix):
const hasOwnProperty = Object.prototype.hasOwnProperty;
function getOutlinedModel(response, reference, parentObject, key, map) {
const path = reference.split(':');
const id = parseInt(path[0], 16);
const chunk = getChunk(response, id);
let value = chunk.value;
// FIXED: Validate property ownership before accessing
for (let i = 1; i < path.length; i++) {
if (hasOwnProperty.call(value, path[i])) {
value = value[path[i]];
} else {
return undefined; // Block prototype access
}
}
return map(response, value);
}
Why ‘hasOwnProperty’ is Cached
The hasOwnProperty reference is cached at module load time (const hasOwnProperty = Object.prototype.hasOwnProperty) before any untrusted input is processed. This prevents attackers from shadowing or overriding the method.
The check also uses call() instead of invoking it directly on the object:
// VULNERABLE — Can be shadowed
value.hasOwnProperty(key)
// FIXED — Uses cached reference
hasOwnProperty.call(value, key)
Prototype Pollution in CVE-2025-55182: A Detailed Technical Breakdown
Here is the in-depth technical breakdown of prototype pollution in CVE-2025-55182:
1. Prototype Pollution Mechanism
In JavaScript, all objects inherit from Object.prototype. If an attacker changes this prototype, every object automatically inherits the injected values. This is the basis of prototype pollution.

Modifying Object.prototype affects all objects, giving attackers broad influence over client-side behavior.
2. The Vulnerable Code

This function returns properties without checking ownership, allowing polluted prototype properties to be accessed.

How CVE-2025-55182 Works
Here is how attackers use React2Shell:

The React Flight protocol serializes component trees for server-client communication. The vulnerability appears in how RSC decodes these serialized payloads.
1. Malicious Server (Attacker-Controlled): an attacker operates a rogue server that crafts and delivers manipulated React Server Component (RSC) responses. These responses contain hidden payloads designed to exploit weaknesses in the client’s deserialization logic and trigger prototype pollution.
2. Sends RSC payload with “proto” keys: the attacker embeds dangerous __proto__ keys inside the RSC JSON stream. These keys are intentionally placed to alter the prototype chain during deserialization, enabling unauthorized property injection into core JavaScript objects.
3. Vulnerable React 19.0.0 Client deserializes: a React 19.0.0 client receives the malicious payload and begins processing it. Due to the vulnerable deserialization mechanism, the client treats the attacker-supplied structure as legitimate and processes it without adequate validation safeguards.
4. reviveModel() assigns without hasOwnProperty check: React’s reviveModel() function assigns payload values directly to objects without verifying ownership using hasOwnProperty. This missing check allows inherited prototype properties to be overwritten, creating the ideal conditions for prototype pollution.
5. Object.prototype polluted on CLIENT: injected keys modify Object.prototype, causing every object in the client environment to inherit the attacker’s malicious properties. This broad, environment-wide contamination enables deep and unpredictable security consequences across the application.
6. Client-side application code uses polluted properties: the application unknowingly interacts with manipulated object properties. Normal logic begins reading or executing attacker-injected values, causing downstream corruption of data flows, misrouting of logic, or unsafe behavior within the browser environment.
7. Security bypasses, data leaks, XSS, DoS: this pollution can enable severe attacks, including bypassing client-side checks, leaking sensitive data, triggering stored or reflected XSS, or crashing parts of the application. Attackers gain powerful control over client behavior and stability.
The worrying fact is all of these above steps can be carried out using a single crafted HTTP request without authentication, no valid session, and no special environment configuration.
This is not server-side RCE. The vulnerability affects the client’s browser, not the server.
Real-World Attack Scenarios
Here are the real world attack scenarios:
Example #1: Authentication Bypass
Attacker makes the victim’s browser think they’re an admin when they’re not:
Vulnerable code pattern:

After prototype pollution:

The potential impact:
- Normal user gains admin privileges in browser session
- Can access admin panels
- Can perform privileged operations
- Can modify/delete data they shouldn’t access
Example #2: Input Validation Bypass
Attacker disables security features like CSRF protection, input validation, or rate limiting.
Here is the vulnerable code pattern:

After prototype pollution:

Here is the the potential impact:
- XSS attacks succeed
- SQL injection possible
- CSRF tokens ignored
- Rate limiting disabled
Example #3 Data Exfiltration
Attackers access sensitive data that should be hidden.
Here is the vulnerable code pattern:

After prototype pollution:

Here is the potential impact:
- PII leaked
- Session tokens exposed
- API keys revealed
- Financial data stolen
Example# 4: Denial of Service
Attacker crashes the victim’s application or browser.
Here is the vulnerable code pattern:

After prototype pollution:

Here is the potential impact:
- Application crashes
- Browser tab freezes
- Infinite loops possible
- Memory exhaustion
Example #5: DOM Manipulation / XSS
Attacker injects malicious HTML/JavaScript into victim’s page.
Here is the vulnerable code pattern:

After prototype pollution:

Here is the potential impact:
- Steal session cookies
- Redirect to phishing sites
- Inject keyloggers
- Steal credentials
React2Shell (CVE-2025-55182) Attack Capabilities
A. What Attackers Can Do
1. Bypass authentication in victim’s browser
2. Disable input validation (enable XSS)
3. Steal data from victim’s browser (cookies, localStorage, session data)
4. Crash the application in victim’s browser tab
5. Execute JavaScript in victim’s browser context
6. Bypass CSRF protection if checks rely on object properties
7. Escalate privileges within the client-side application
8. Manipulate DOM and inject malicious content
B. What Attackers Cannot Do
1. Execute commands on the server (no shell access)
2. Access server files
3. Modify server database directly
4. Install backdoors on the server
5. Persist after page reload
6. Compromise the server itself
7. Affect other users (only individual vic
How to Patch (CVE-2025-55182)
React 19.0.1, 19.1.2, and 19.2.1 include two critical fixes:
Fix 1: hasOwnProperty Check in Module Loading

The patch adds an explicit hasOwnProperty check to verify the property exists on the object itself, not inherited from the prototype chain.
Fix 2: Special Handling for __proto__

Explicit handling for the __proto__ key ensures it’s deleted/neutralized instead of polluting the prototype chain.
React2 Shell ( CVE-2025): Remediation Methodology
Here are some immediate actions you can take:
A. Upgrade React to patched versions

B. Upgrade Next.js to patched versions

3. Verify your versions
npm list react react-dom next
Best Practices To Prevent CVE-2025-55182
Below, we have presented a list of the best practices to prevent exploitation from React2Shell vulnerability:
1. Defense- in -Depth
- Always validate user input on the server
- Use server-side session management
- Implement proper RBAC (Role-Based Access Control) on the backend
2. Security Headers
Strengthen client-side security by enforcing restrictive browser policies. Content-Security-Policy: default-src ‘self’; script-src ‘self’
3. Harden the Prototype
Freezing the global prototype helps prevent accidental or malicious modification:
Object.freeze(Object.prototype);
4. Code Review
Look for insecure patterns that rely on prototype-inherited properties:
if (obj.someProperty) { /* dangerous if relies on prototype */ }
5. Use hasOwnProperty in Security Checks
Always validate properties explicitly owned by the object:
if (Object.prototype.hasOwnProperty.call(obj, ‘isAdmin’)) {
// Safe check
}
How to Patch the CVE-2025-55182 in Google Cloud
WAF rules help reduce immediate risk, but the only reliable long-term fix is to patch the frameworks themselves. If you’re running React or Next.js on Google Cloud, upgrade to the latest stable versions as soon as possible. Here is how you can do this upgrade:
- Cloud Run, Cloud Run functions, and App Engine: update your application dependencies with the patched framework versions and redeploy.
- Google Kubernetes Engine (GKE): rebuild your container images with the updated framework versions and redeploy your pods.
- Compute Engine: Google’s public OS images do not ship with React or Next.js by default. If you’re using a custom image that includes these packages, update your workloads and ensure WAF protections are enabled in front of all services.
- Firebase: if you use Cloud Functions for Firebase, Firebase Hosting, or Firebase App Hosting, update your dependencies and redeploy. Firebase Hosting and App Hosting are also enforcing an additional rule to help block exploitation of CVE-2025-55182 across both custom and default domains.
Patching your applications removes the vulnerability at the source and is essential for maintaining the security and integrity of your workloads.
How to Patch the CVE-2025-55182 in Microsoft Azure
Here is a short, clear remediation as provided by the Microsoft Azure blog: Protect against React RSC CVE-2025-55182 with Azure Web Application Firewall (WAF), which keeps all original code blocks intact while making the narrative more natural and concise:
1. Add a Custom WAF Rule to Mitigate CVE-2025-55182
If you need a CVE-specific safeguard while patching your applications, you can add custom WAF rules designed to detect patterns associated with CVE-2025-55182. These rules are configured to block traffic, so test them in a staging environment before enabling them in production.
2. Implement Custom Rules for WAF on Application Gateway

3. Custom Rules for WAF on Azure Front Door

In short, the above WAF rule blocks potentially malicious requests linked to CVE-2025-55182 by detecting React/Next.js action headers, risky content types, and prototype-pollution keywords in the request body.
How to Patch CVE-2025-55182 Vulnerability in AWS Cloud
As an extra layer of protection, you can create a custom AWS WAF (Web Application Firewall) rule to help mitigate this issue. The sample rule below is configured to BLOCK by default. Make sure to test it in your environment first to confirm that it works as expected and doesn’t interfere with normal traffic.

The above rule blocks POST requests from React Server Component / Next.js App Router action payloads with specific internal markers against a suspected or known React/Next.js RCE-style attack.
Our Testing Methodology
To validate the impact of CVE-2025-55182, our team followed a multi-phase testing approach. Each phase helped us understand how the vulnerability behaves in real-world scenarios and why early assumptions were incorrect.
Phase 1: Initial Testing
We created an isolated AWS EC2 environment and tested by sending malicious payloads to a vulnerable React server. This revealed server-side behavior but didn’t demonstrate the actual client-side vulnerability.
Learning: We tested the wrong attack direction.
Phase 2: Patch Analysis
We reviewed the actual React patch (PR #35277) and discovered:
- The vulnerability is client-side
- Affects RSC deserialization on the client
- Not related to Server Actions processing
Phase 3: Prototype Pollution Proof
We created standalone JavaScript tests demonstrating prototype pollution:

Phase 4: Interactive Demonstrations
We built interactive HTML demos showing:
- Authentication bypass
- Validation bypass’
- Data exfiltration
- Application crash (DoS)
Complete Attack Example
Setup:
- Attacker controls evil.com running Next.js
- Victim uses React 19.0.0 in their browser
- Target is victim’s banking app at bank.com
Attack Flow
Step 1: Victim visits evil.com (via phishing email)
Step 2: Attacker’s server sends malicious RSC payload:

Step 3: Victim’s React 19.0.0 client deserializes payload.
Step 4: Object.prototype is now polluted in the victim’s browser.
Step 5: Victim navigates to bank.com in the same browser session.
Step 6: Banking app checks: if (user.isAdmin) { showAdminPanel(); }
Step 7: Check passes (user.isAdmin inherits true from prototype).
Step 8: Victim sees admin panel and can:
- Transfer money from any account
- View all customer accounts
- Modify permissions
- Export sensitive data
The server (bank.com) is not compromised. The victim’s browser has been tricked into bypassing all client-side security checks.
Our Research Process
Through our research, we:
- Initially tested the wrong attack vector (server-side)
- Discovered the truth through patch analysis
- Created comprehensive demonstrations
- Built interactive proof-of-concepts
- Documented findings
This reinforces the importance of:
- Reading actual patches, not just security advisories
- Understanding attack vectors before testing
- Honest disclosure of research methodology
- Scientific rigor over sensationalism
Key Takeaways
CVE-2025-55182 represents one of the most impactful vulnerabilities disclosed in the React and Next.js ecosystem to date. Because the flaw affects default configurations and can be exploited with a single HTTP request, organizations must patch immediately, verify remediation, and strengthen dependency governance.
If you suspect you may already be targeted, reach out to your incident response provider or the Wiz IR team for investigation support.
Here are some key takeaways:
- Client-Side, Not Server-Side: This vulnerability impacts the victim’s browser only — the server remains uncompromised.
- Complete Security Bypass: Allows full authentication bypass, data theft, XSS, and even denial-of-service inside the user’s browser.
- CVSS 10.0 Is Justified: The ability to fully compromise client-side security warrants a critical severity rating.
- Immediate Patching Required:
All React 19.x users should upgrade to the patched versions without delay. - Defense in Depth: Client-side checks are never sufficient on their own; always enforce security on the server.
References resources
A. Official Sources
https://github.com/facebook/react/security/advisories/GHSA-fv66-9v8q-g76r)
Critical Security Vulnerability in React Server Components – React
B. Educational Resources
https://portswigger.net/web-security/prototype-pollution
Update Log:
February 10, 2026: This post was refreshed with expanded Next.js and React RSC coverage, a reproducible lab setup, and an added Proof of Concept (PoC) reference. Patch and mitigation guidance were also updated to help teams respond faster.
Appendix: Test Code
A. Standalone Prototype Pollution Test

B. Run the Test
node test.js
C. Expected Output (Vulnerable Build)

FAQs on CVE-2025-55182
Yes. If your product uses React 19.x with Server Components, customers’ browsers can be manipulated, leading to data exposure, session hijacking, and unauthorized actions.
Potentially yes. Any client-side data leakage (cookies, tokens, personal data) can create compliance violations, especially under GDPR and PCI DSS where protection of user data is mandatory.
No. Servers are not directly compromised. However, compromised client behavior may lead to fraudulent actions being submitted to your backend.
High. Consequences include account takeovers, fraudulent transactions, customer data leaks, brand damage, increased support costs, and potential legal exposure.
Low. Upgrading to patched React/Next.js versions is typically a drop-in update, with minimal code changes required.
If your platform uses affected React versions, yes — transparency builds trust. Especially for fintech, healthcare, or SaaS platforms handling sensitive data.
Only temporarily. Most teams complete the upgrade within hours. It’s a priority patch, not a long-term blocker.
Yes. Because the victim’s browser can be tricked into acting as an admin, attackers could trigger unauthorized actions like money transfers or account changes.



