Intro and live proof of concept
Ladies and gentlemen, boys and girls, this is it. That's the proof of concept. This is the exploit. Let me show you. So, over here in my terminal, I have just spun up a next app with npm for the React 2 shell vulnerability. I'm using an old version here, 16.0.6, because this is now patched. But you'll note, oh, yep, one critical severity vulnerability. I've spun up the application. It's running here at localhost 3000. And in a separate terminal, let me move into the CVE folder here. And we do have a proof of concept.py. And I'll minimize this here. Make this a smidge smaller so you can see it. But running the puck, there's calc. So here's the gist. In case you missed it, a lot of the internet was running around like a chicken with their head cut off because there was a critical security vulnerability in React. Not something we tend to have on our 2025 bingo card. Shout out to you, Ed. This is an unauthenticated remote code execution vulnerability and they recommend upgrading immediately because this is CVSS 10.0, the highest it goes.
Scope: affected versions and ecosystem impact
Vulnerability is present in versions 19.0, 19.1.0, 19.1.1 and 19.2.0 of a lot of the stuff that's using React server. Now let me say I am not a front-end guy. I don't do a whole lot with React or Nex.js JS and I'll be honest, I don't know much about it. So, I'm going to be realistically latching on to the coattails of others here. But, I thought, you know what? Still, the fireworks are kind of fun. And I'll leave, of course, a link to all of this in the video description because you will want to update all of the different versions of the software that you might be using here. Nex.js, React Router, blah blah blah. But shout out, kudos, credit where credit is due. Lachlan Davidson reported this to Meta. And I don't mean to be making light of this. Forgive me. I know. Seriously, genuinely, this is a 10.0 critical vulnerability, pre-authentication remote code execution vulnerability in React server components. So, a whole lot of the internet could catch on fire.
My buddies over at Whiz are saying almost 40% of cloud environments contain instances of Nex.js or React that are vulnerable. Considering just Nex.js, JS the framework itself is present in almost 70% of environments and just over 60% of those are public and open to the internet. So doing the quick math on that 44% of all cloud environments have publicly exposed Nex.js instances and I don't know if you caught it but I had meant to showcase like a completely default vanilla flat classic configuration of just running a Nex.js JS app with React that's still vulnerable or was now that this is patched upgrade. And to be clear, it is two different vulnerabilities that we're kind of tracking here. One that I showed the NVD entry for again was React, but 66478 is specific to Nex.js. The vulnerability originates in the upstream React implementation. That's our 55182 reference, but this advisory with 66478 is the one specific to the app router use in Nex.js JS. Again, link in all of the video description. But let's talk about the proof of concept because I think the internet saw a little bit of a funny boo boo.
Proof-of-concept history and attribution
The other night a lot of folks were screaming and shouting about this GitHub repository and that hit the streets first, but it didn't actually have working proof of concept code. It wasn't the actual exploit. So, a little bit more time passed. People are kind of wandering, scratching their head, wondering what the heck this thing's going to be. But, credit where credit is due, of course. I saw this from Moritz Samp and they had shared oh the full rce remote code execution proof of concept is now live. They were doing some analysis and they've got their own resource and repository here and we could dig into that. I saw some of the chatter and conversations online that followed this and a lot of folks are saying like look this is it. Yeah, this is the real one explanation and full rce proof of concept for the react vulnerability. This is the proof of concept that I showcased at the beginning of the video. And let me try to walk through this, but please, please, please let me add the grain of salt. I don't exactly know all the ins and outs of this. So, take that for what it is.
Technical root cause: React server flight protocol and deserialization
React offers server functions, which are basically like RPC or remote procedure call over HTTP, hypertext transfer protocol. They fetch data from other instances to ensure low latency or perform authenticator requests that the client doesn't have credentials for. React does this with the React flight protocol. And that ends up serializing or deserializing values. That's all kind of represented or wrapped as different chunks. And you can see a little bit of a logic here to this. Zero as kind of the first index is set with some sort of string that looks like within square braces dollar sign one to represent some entity, some abstract object. And then later in the next entry ID of one here, they add more structure to that object noting that it's a fruit with a given property of a name of a fruit name and that property's value could be something like cherry. And then those are referenced. They end up deserializing data to represent a fruit object with a given name, cherry. Of course, it can do a heck of a lot more, but I think maybe that's enough of an understanding.
Exploitation chain: prototype access to exec
The vulnerability ends up being in how this actually isn't going to be checked or react itself not verifying whether or not the key is set to the object. So you could retrieve the prototype or a little bit more metadata fields values kind of inherent and implicit to that abstract idea. They use this where they take in that ID or chunk ID zero dollar sign one but actually accessing some proto prototype special dunder function to be able to access that not function but the constructor and the constructor to actually access the initialization function of that object. Again please let me add the background context. I don't know if that's the right or best explanation. I will leave it to the experts again with the link in the video description. But when they start to play with these because these are all a synchronous with await and async calls those are thenable when you have some other opportunities to have things happen after some data is processed then you could have it basically run that function. Well, I think there is a gimmick there because you can't as easily call the function, but you could retrieve the function constructor. Then you'd want to eventually run it, execute it, but have a user controlled value like what you want to fire and execute. That's not as easy though. Apparently, I think there are some other artifacts left over within the language and the way that would derialize or work with the data. I guess slice is a function that gets in the way, but big shout out to Maple 3142. They had this brilliant idea that the get chunk capability grabs a chunk at ID zero, but it could also mean that it could resolve to a fake chunk, but not a resolved value. It's raw value. I'm not going to pretend that I know everything that's happening here, but that's cool. Ultimately, they end up with enough staging that they could craft an object with some vague properties that the proto and prototype is actually able to decorate and craft a chunk which could use some of the more native natural what we're probably used to seeing in that CTF or capture the flag world where we could execute a actual subprocess and run some system command process. ual.require child process and exec sync with whatever you want to fire off. Maybe it's a reverse shell. Maybe it's some code. Maybe it's the calculator as a proof of concept. I think a lot of folks were laughing, the folks that know, and forgive me I don't, that this does feel like a capture the flag or CTF-like vulnerability. But a little bit more damning is that that all happens. All that deserialization work that's done before the requested action is even validated in some of the other functions that are part of the process here. So even setting a header is enough to trigger the vulnerability. I believe that's from React server actions in one of the old representations or how they used to call a lot of the react server components work. So all they end up doing for the patch is just making a little silly if statement here. Hey are you tracking the proto? Do you know the prototype of everything in the chunk? Does that exist for yourself as an object? But look, I don't want to play pretend that I know everything that's happening behind the scenes here. I was the one kind of sitting with my popcorn waiting to see, ooh, when's there going to be a pock drop? Is anybody going to share the street deets? And again, shout out Maple. Maple 3142. I saw them share this video, a proof of concept for the CVE and a gist that includes the syntax of at least the request that gets sent because you'll note they're experimenting with this in Burpswuite. They just got OBS running to record this. They've spun up a flat default React and next app and then they just click the go button in Burpuite when that's set to the target to send this request. The gist that they share, of course, link in the video description. Credit where credit is due. It's just the post request with the prototype crafted chunk all set there. And they use XCalc to demonstrate this. But again, remember like this goes to show how this could very well be weaponized because like this is all that you tweak and change to do anything else to get a reverse shell connection to run some other malware virus whatever the heck. Look, I don't mean to just be adding to the noise with all this. I think this is going to probably explode to the sort of log for shell scenario. So sorry for that PTSD and trauma. But react to shell sounds like really what we're going to end up having for our Thanksgiving 2025. A lot of folks are going to be doing a lot of awesome stuff to help track this. I'll leave of course again links in the video description where I can for blue team cheat sheet. Folks will be sharing different scanners. I know there'll be honeypots or oh little things out and about so we could see this out on the internet. So, you're probably going to see an absolute flood of all of these advisories, reports, releases, tools, scanners, more proof of concepts, different things to see this out across the internet. But I don't want you to have your head in the sand here as more proof of concepts hit the street. Be all out and about on the internet. Looks like here's another in Python that could probably get a full-blown reverse shell. Yeah. Yeah. Yeah. Here's functionality for that specific to Linux. It looks like this is going to blow things up a little bit again. I think for all you Versel people, looks like Big G is sharing the fact that oh, their little waffy boy will go ahead and lock that down. That will block the variant. But patch, upgrade, patch your potatoes, patch the poop out of it. Do what you got to do.