Critical Security Vulnerabilities Discovered in React and Next.js: Immediate Upgrades Recommended

Software Security

Urgent security vulnerabilities (CVE-2025-55182, CVE-2025-55183, CVE-2025-55184) affecting React Server Components and Next.js versions have been discovered, enabling potential code execution, data theft, and cryptomining. Users are strongly advised to upgrade React to 19.2.1 and Next.js to versions >=13.3 immediately to mitigate severe risks.

It is crucial to immediately upgrade your React and Next.js applications if they are in production environments. Specifically, upgrade React versions from 19.0.0 to 19.2.1 and ensure Next.js is at version 13.3 or higher.

On December 3rd, a critical security vulnerability (CVE-2025-55182) was discovered in React Server Components, affecting versions 19.0.0 through 19.2.0 of react-server-dom-webpack, react-server-dom-parcel, and react-server-dom-turbopack. Subsequently, on December 11th, two additional vulnerabilities (CVE-2025-55183 and CVE-2025-55184) leading to Denial of Service and Source Code Exposure were found, impacting virtually all Next.js versions from v13.3 upwards. These vulnerabilities share a maximum severity score of 10.0, indicating extreme risk.

This series of exploits highlights significant issues that require immediate attention. Understanding how such vulnerabilities arise offers valuable insights into frontend development security, particularly concerning framework architecture.

How These Vulnerabilities Occurred

The core issue stems from major flaws in how React deserialized client-sent data on the server, specifically within React’s Flight protocol—the internal mechanism for data exchange between server and client. The server failed to safely handle malformed serialized data, enabling malicious actors to achieve remote code execution and source code leakage.

For a deeper technical understanding, resources like Moritz Sanft's breakdown of the exploit and Better Stack’s video explanation provide excellent insights. In essence, the exploit leverages an oversight in React's handling of client-sent data combined with specific JavaScript language quirks.

The primary exploit allowed payloads to access properties of objects that were not their own, granting attackers access to any object’s prototype. This access facilitates various malicious actions due to JavaScript's behavior, including:

  • Awaiting Objects with then Properties: JavaScript allows objects with a then property to be awaited, causing the then function to execute automatically.
    const func = () => console.log("WHY DOES THIS RUN 😱?!");
    const obj = { something: "something", then: func };
    await obj; // This prints out "WHY DOES THIS RUN 😱?!"
    
  • Prototype Chain Access: All JavaScript objects possess a prototype, enabling inheritance. If a property access fails on an object, it attempts to access it on its prototype. This allows access to properties up the prototype chain:
    console.log(({}).__proto__); // Prints out the prototype object.
    
  • Dynamic Code Execution with Function: The Function object can execute code from a string, offering a powerful avenue for attackers:
    Function("console.log('oh no!');")();
    
  • Accessing Object and Function Constructors via Prototypes: Attackers can traverse the prototype chain to obtain the Object's constructor and, further, the Function's constructor. Given that Function instances can execute arbitrary string code, this forms a critical part of the exploit chain:
    const code = { a: 1 }.__proto__.constructor.constructor;
    code("console.log('💀')")();
    
    All these JavaScript characteristics were combined to create the exploit.

The fix, visible in React's original pull request, involves using hasOwnProperty.call(moduleExports, metadata[NAME]) checks. This prevents return moduleExports[metadata[NAME]]; from executing properties not directly belonging to the object, effectively blocking malicious payloads from referencing external object properties.

Community Perspectives

The incident sparked significant discussion, particularly on platforms like Y Combinator, revealing a split in opinions. A notable comment from the discussion by "coffeecoders" highlights a deeper architectural concern:

"We can patch hasOwnProperty and tighten the deserializer, but there is deeper issue. React never really acknowledged that it was building an RPC layer. If you look at actual RPC frameworks like gPRC or even old school SOAP, they all start with schemas, explicit service definitions and a bunch of tooling to prevent boundary confusion. React went the opposite way: the API surface is whatever your bundler can see, and the endpoint is whatever the client asks for. My guess is this won’t be the last time we see security fallout from that design choice. Not because React is sloppy, but because it’s trying to solve a problem category that traditionally requires explicitness, not magic."

This critique suggests that React's implicit RPC-like behavior, without explicit schemas or service definitions, could inherently lead to security vulnerabilities. Such discussions offer valuable insights into the design principles of major frameworks and the distinctions between server components and Server-Side Rendering (SSR).

Potential Impact

According to Wiz.io's deep dive into the incident, bad actors have exploited these vulnerabilities to:

  • Perform cryptomining by running shell scripts on affected servers.
  • Scrape cloud and application secrets.
  • Download entire source code repositories.
  • Hold sensitive information for ransom.
  • Execute virtually any code, given the nature of the exploit.

The simplicity of the fix, contrasted with the severity and breadth of the potential impact, underscores the importance of prompt updates and rigorous security practices in web development. Ensure your React and Next.js installations are up-to-date to protect against these critical threats.