Skip to content
OopsSec Store - Walkthroughs
Go back

React2Shell: Exploiting CVE-2025-55182 in React Server Components

Edit page

This writeup walks through CVE-2025-55182, a remote code execution bug in React Server Components. The vulnerability sits in the Flight protocol’s deserialization logic and requires no authentication to exploit.

Table of contents

Open Table of contents

Lab environment setup

From an empty directory:

npx create-oss-store oss-store
cd oss-store
npm start

Or with Docker (no Node.js required):

docker run -p 3000:3000 leogra/oss-oopssec-store

Head to http://localhost:3000 and make sure the app loads.

Vulnerability overview

React Server Components (RSC) talk to the server through a serialization protocol called Flight. When the browser loads a page or fetches server components, it sends Flight requests to the root endpoint.

The server-side deserializer processes this serialized component data without validating property names. That missing check is what makes React2Shell (CVE-2025-55182) possible.

Exploitation

Intercepting requests with Burp Suite

Set up Burp Suite to intercept HTTP traffic:

  1. Open Burp Suite and navigate to Proxy → Intercept
  2. Enable interception
  3. Configure your browser to use Burp as an HTTP proxy (127.0.0.1:8080), or use Burp’s built-in browser
  4. Reload http://localhost:3000
  5. Forward the intercepted request to allow the page to load
  6. Right-click any captured request and select “Send to Repeater”
  7. Disable interception and switch to the Repeater tab

Burp Suite Repeater tab showing the intercepted request

Crafting the payload

Replace the entire request in Burp Repeater with the exploit payload from the CVE-2025-55182 proof of concept repository. The payload abuses the Flight protocol to inject JavaScript that runs on the server.

Firing it off

Send the modified request. The server tries to deserialize it as a normal Server Components response but ends up executing the injected code instead.

Burp Suite showing the exploit response

Retrieving the flag

The HTTP response comes back as a React error payload. Buried in there are the contents of .env.local, including the flag:

OSS{r3act2sh3ll}

The server ran cat .env.local and sent the output back to us.

Flag validation in OopsSec Store

Vulnerable code analysis

The bug is in how the RSC deserializer traverses object properties:

value = value[path[i]];

There’s no allowlist of permitted property names, no own-property check, and the full prototype chain is accessible. So when an attacker supplies constructor as a property name, the deserializer resolves:

chunk.constructor.constructor === Function;

That’s the Function constructor. From there:

Function("malicious code")();

Game over. The whole thing boils down to trusting client-controlled property names during deserialization.

Impact

With RCE on the server, what happens next depends on the environment. An attacker could read secrets straight out of environment variables and config files, drop a cryptominer or backdoor, pivot into internal networks through cloud metadata endpoints (169.254.169.254), or, if the server has publish access to a package registry, poison downstream dependencies.

Remediation

If you’re running Next.js or any framework that uses React Server Components:

  1. Upgrade React to the latest patched version
  2. Upgrade Next.js to the latest patched version
  3. Redeploy

CVE-2025-55182 dropped on December 3, 2025. Working exploits showed up within hours, and active exploitation was spotted the next day. Patch now if you haven’t already.


Edit page
Share this post on:

Previous Post
Mass Assignment: Admin Privilege Escalation via Signup
Next Post
SQL Injection: From Dropdown to Database Dump