If you ship React Server Components in production and you have not yet patched, stop reading and patch now. This is not hyperbole.

On December 3, 2025, the React team disclosed CVE-2025-55182, a pre-authentication remote code execution vulnerability in React Server Components with a CVSS score of 10.0 -- the maximum possible severity rating. Dubbed "React2Shell" by the security community, this vulnerability allows an attacker to execute arbitrary code on any vulnerable server using nothing more than a single crafted HTTP request. No authentication required. No special configuration needed. A default create-next-app deployment built for production is exploitable out of the box.

Then on January 26, 2026, a follow-up vulnerability (CVE-2026-23864, CVSS 7.5) disclosed additional denial-of-service attack vectors in the same React Server Components Flight protocol. This article covers both vulnerabilities, their exploitation in the wild, and the concrete steps every React developer must take.

Understanding the Flight Protocol

To understand why these vulnerabilities are so severe, you need to understand the React Server Components Flight protocol.

When a React Server Component renders on the server, the result is serialized into a special format called the "Flight" payload. This payload is transmitted to the client, where it is deserialized and rendered into the DOM. Similarly, when a client calls a Server Action (a function that runs on the server), the arguments are serialized on the client and deserialized on the server.

The Flight protocol is the serialization/deserialization mechanism that makes this work. It handles complex JavaScript objects, React elements, promises, and other data types that need to cross the client-server boundary.

The critical flaw: the Flight protocol's server-side deserialization did not properly validate incoming payloads. It treated client-supplied data with an implicit trust that is fundamentally inappropriate for a network boundary.

CVE-2025-55182: React2Shell (CVSS 10.0)

The Vulnerability

The root cause is insecure deserialization in the react-server-dom-webpack, react-server-dom-turbopack, and react-server-dom-parcel packages. When processing an incoming Flight payload, the server creates internal "Chunk" objects to represent the deserialized data. The vulnerability allows an attacker to:

  1. Craft a fake Chunk object in the request body
  2. Submit it to any Server Function endpoint via a POST request
  3. Because React does not validate the payload, it treats the fake object as genuine
  4. When React resolves the Chunk, the attacker gains control of internal request state
  5. Several internal properties become accessible as "gadgets" to execute arbitrary JavaScript

The exploit chain ends with full remote code execution under the Node.js runtime. The attacker gains the same privileges as the Node.js process -- which, in many deployments, means complete server compromise.

Affected Versions

Package Vulnerable Versions Patched Versions
react-server-dom-webpack 19.0.0, 19.1.0, 19.1.1, 19.2.0 19.0.1+, 19.1.2+, 19.2.1+
react-server-dom-turbopack 19.0.0, 19.1.0, 19.1.1, 19.2.0 19.0.1+, 19.1.2+, 19.2.1+
react-server-dom-parcel 19.0.0, 19.1.0, 19.1.1, 19.2.0 19.0.1+, 19.1.2+, 19.2.1+

Affected frameworks include:

  • Next.js versions >= 14.3.0 (canary), >= 15.x, >= 16.x (when using App Router)
  • React Router (with RSC support)
  • RedwoodSDK
  • Waku
  • Any custom framework using the React Server Components Flight protocol

Real-World Exploitation

Exploitation activity was detected as early as December 5, 2025 -- just two days after public disclosure. According to reports from Palo Alto Networks Unit 42, Google Cloud Threat Intelligence, and AWS Security:

  • Initial exploitation was primarily from red team assessments and security researchers
  • Threat actors rapidly developed automated exploit tooling
  • The majority of real-world malicious exploitation involved cryptocurrency mining payloads
  • China-nexus cyber threat groups were identified as rapidly exploiting the vulnerability
  • Multiple subsequent payloads beyond coin miners were observed, including reverse shells and data exfiltration tools

Microsoft published a detailed defensive guide, and multiple cloud providers issued emergency advisories.

React2Shell attack flow diagram showing the exploitation chain The React2Shell exploitation chain: from crafted payload to server compromise

CVE-2026-23864: Denial of Service (CVSS 7.5)

The Vulnerability

Disclosed on January 26, 2026, CVE-2026-23864 addresses multiple denial-of-service vulnerabilities in the same Flight protocol. Attackers can send specially crafted HTTP requests to Server Function endpoints that cause:

  • Server crashes from malformed payloads
  • Out-of-memory exceptions by sending extremely large array payloads
  • Excessive CPU usage through deeply nested object structures

Affected Versions

This vulnerability affects a broader range of versions since it was discovered in code that existed across more releases:

  • React versions 19.0.0 through 19.2.3
  • Next.js versions 13.x, 14.x, 15.x, and 16.x

Patched Versions

Fixes are available in React versions 19.0.4, 19.1.5, and 19.2.4. The patch limits the array size that can be sent in a Flight request, adds depth limits for nested objects, and implements proper resource accounting.

How to Check If You Are Vulnerable

Step 1: Determine If You Use React Server Components

If your application does not use a server, or does not use a framework/bundler that supports React Server Components, you are not affected.

# Check your React version
npm list react react-dom react-server-dom-webpack react-server-dom-turbopack

# Check for Server Components usage in your codebase
grep -r "use server" --include="*.tsx" --include="*.ts" --include="*.jsx" --include="*.js" src/

If you see "use server" directives in your code, you are using Server Actions and are potentially affected.

Step 2: Check Your Versions

# For npm projects
npm audit

# For yarn projects  
yarn audit

# Specifically check for the CVEs
npm audit --json | jq '.vulnerabilities | to_entries[] | select(.value.via[].url | contains("CVE-2025-55182") or contains("CVE-2026-23864"))'

Step 3: Patch Immediately

# Update React packages to the latest patched versions
npm install react@latest react-dom@latest react-server-dom-webpack@latest

# If using Next.js, update to the latest patched version
npm install next@latest

# Verify the update
npm list react react-dom next

Mitigation for Those Who Cannot Patch Immediately

If you absolutely cannot update your React version right away, here are temporary mitigations:

1. Web Application Firewall Rules

If you use a WAF (Cloudflare, AWS WAF, etc.), add rules to inspect and block malicious Flight payloads:

{
  "name": "Block React2Shell Exploit Attempts",
  "description": "Blocks known CVE-2025-55182 exploit patterns",
  "action": "block",
  "expression": "(http.request.method eq \"POST\" and http.request.body.mime_type eq \"text/x-component\" and http.request.body.size gt 50000)"
}

This is a coarse rule and should be refined for your specific application. It is not a substitute for patching.

2. Rate Limiting on Server Action Endpoints

// middleware.ts (Next.js example)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute
const MAX_REQUESTS = 100;
const requestCounts = new Map<string, { count: number; resetTime: number }>();

export function middleware(request: NextRequest) {
  // Only apply to Server Action requests
  if (request.headers.get('content-type')?.includes('text/x-component')) {
    const ip = request.headers.get('x-forwarded-for') || 'unknown';
    const now = Date.now();
    const record = requestCounts.get(ip);
    
    if (record && now < record.resetTime) {
      if (record.count >= MAX_REQUESTS) {
        return new NextResponse('Rate limited', { status: 429 });
      }
      record.count++;
    } else {
      requestCounts.set(ip, { count: 1, resetTime: now + RATE_LIMIT_WINDOW });
    }
  }
  
  return NextResponse.next();
}

3. Disable Server Actions Entirely (Nuclear Option)

If you do not use Server Actions, you can disable them in Next.js:

// next.config.js
module.exports = {
  experimental: {
    serverActions: {
      enabled: false,
    },
  },
};

Lessons Learned

1. Serialization Boundaries Are Trust Boundaries

The Flight protocol's fundamental error was treating the client-server serialization boundary as a trusted internal interface rather than an untrusted network boundary. This is a well-known antipattern, but it keeps recurring because serialization layers are often built for functionality first and security second.

Takeaway: Any data that crosses a network boundary -- regardless of how "internal" the protocol feels -- must be treated as untrusted input. Validate, sanitize, and constrain.

2. Framework Defaults Must Be Secure

CVE-2025-55182 was exploitable in a default create-next-app configuration with zero developer modifications. This means the vulnerability was not caused by developer misconfiguration -- it was built into the framework's default behavior.

Takeaway: If your framework or library has a default configuration, that default must be secure. Security cannot be opt-in.

3. The RSC Ecosystem Is Still Maturing

React Server Components are a powerful architecture, but they are still relatively new. The Flight protocol had not undergone the same level of adversarial security scrutiny as more established serialization formats.

Takeaway: When adopting new architectural patterns (especially those involving serialization across trust boundaries), factor in the maturity and security track record of the implementation. New does not mean insecure, but it does mean less battle-tested.

4. Patch Velocity Matters

The two-day gap between disclosure and active exploitation underscores the critical importance of rapid patching. Organizations that had automated dependency update pipelines (Dependabot, Renovate) with fast merge processes were protected much sooner than those relying on manual review cycles.

Takeaway: Invest in your dependency update pipeline. The ability to ship a critical patch in hours rather than days is a security capability.

Timeline of Events

React 19 vulnerability timeline from discovery to active exploitation Timeline of the React 19 vulnerability from discovery through active exploitation

Date Event
December 3, 2025 CVE-2025-55182 publicly disclosed by React team
December 5, 2025 First exploitation activity detected in the wild
December 11, 2025 Additional DoS and source code exposure vulnerabilities disclosed
December 12, 2025 Palo Alto Networks Unit 42 publishes detailed exploitation analysis
December 15, 2025 Microsoft publishes defensive guidance
January 26, 2026 CVE-2026-23864 (DoS vulnerabilities) disclosed
January 26, 2026 Patches released: React 19.0.4, 19.1.5, 19.2.4

Final Checklist

Before you close this article, make sure you have:

  • Checked whether your application uses React Server Components
  • Verified your React and framework versions against the affected versions list
  • Updated to patched versions (React 19.0.4+, 19.1.5+, or 19.2.4+)
  • Updated your Next.js version if applicable
  • Run npm audit or equivalent to verify no known vulnerabilities remain
  • Reviewed server logs for signs of exploitation (unusual POST requests to Server Action endpoints)
  • Considered implementing WAF rules and rate limiting as defense-in-depth measures

React Server Components remain a powerful and valuable architecture. But this incident is a stark reminder that every abstraction layer is also an attack surface, and security must be a first-class concern -- not an afterthought -- in framework design.

Comments