Just to simplify this - our exploitation tests so far have shown that a standard Next.js application created via create-next-app and built for production is vulnerable to CVE-2025-66478 without any specific code modifications by the developer - so this is essentially exploitable out-of-the-box.
Unsafe deserialization is a very 2010 Ruby on Rails sort of vulnerability. It is strangely interesting that such a vulnerability was introduced so late in the lifetime of these frameworks. It must be a very sneaky vulnerability given how cautious we have become around deserialization since then.
These wiz.io blog posts should be banned from HN; AFAICT, they're AI generated. Here's the original post with the details: https://react.dev/blog/2025/12/03/critical-security-vulnerab... - the vulnerability was not found by a Wiz employee at all, and the Wiz article (unlike the react.dev article) does not provide any meaningful technical information.
The important part to know:
- Even if your app does not implement any React Server Function endpoints it may still be vulnerable if your app supports React Server Components.
- The vulnerability is present in versions 19.0, 19.1.0, 19.1.1, and 19.2.0 of: react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack
- Some React frameworks and bundlers depended on, had peer dependencies for, or included the vulnerable React packages. The following React frameworks & bundlers are affected: next, react-router, waku, @parcel/rsc, @vitejs/plugin-rsc, and rwsdk.
It's generated code ("compiled" Javascript); I found it easier to read than the "main" diff in React which was (intentionally, I think?) obfuscated with additional changesets.
It seems like this might be one of the biggest vulnerabilities in recent times...
The default react / nextjs configurations being vulnerable to RCE is pretty insane. I think platform level protections from Vercel / Cloudflare are very much showing their utility now!
I don't have time to look into it right now (def later)!
However, I was curious to see if github copilot can reverse engineer it based on the latest commits and seems that what it is saying aligns with both advisories. It pointed out that it has to do with circular reference handling which sounds to me something that can be easily overlooked.
While this analysis might be completely off, the simple fact that I could get even this information without much efforts is mind-boggling. With better setup it might be able to get more.
With AI now being common place, coordinated timely disclosure is even more important considering the stakes. It is theoretically possible to get an exploit working within minutes. Considering that we see one of these major vulnerabilities annually (and it seems to me around the same time of the year) a bad actor can easily capitalise on the opportunities when presented.
Checked. The answer is no (Claude Opus 4.5 with OpenCode). It wasn't even able to write a scanner to check for the vulnerability that worked. I gave it the diffs and various writeups, and the free access to the source and compiled index.js. It kept trying to cheat by editing the source to add a vulnerability and saying that it got an RCE
It seems like this vulnerability is yet another prototype pollution vulnerability.
There was a TC39 proposal a few years ago [0] that proposed to block the getting/setting of object prototypes using the bracket notation, which would have prevented this vulnerability.
At the moment, every single get/set with a square bracket, which uses untrusted data, needs to do some manual check to see whether variables contain "bad" keys like `__proto__`, `prototype,` `constructor`, and so on. This is incredibly annoying, and doesn't really fix the issue. It's possible also to freeze an object's prototype, but that causes other issues. It's also possible to use Object.create(null), and Object.hasOwn (also known as Object.prototype.hasOwnProperty), but again, this does not scale because it has to be done _every single time_.
Maybe it's time to revisit this from a language perspective, instead of continuous bandaid fixes for this language-specific vulnerability (a similar language-specific vulnerability exists in Python called class pollution, but it's .. extremely uncommon).
On Node.js there are some hardening flags like --disable-proto=throw and --frozen-intrinsics to mitigate/crash on prototype pollution, and to prevent dynamic evals with --disallow-code-generation-from-strings - however, Vercel doesn't seem to support custom node runtime options.
22 comments
[ 3.8 ms ] story [ 60.8 ms ] threadThis might cause quite a lot of chaos and leaked code / credentials over the next couple of weeks.
The important part to know:
- Even if your app does not implement any React Server Function endpoints it may still be vulnerable if your app supports React Server Components.
- The vulnerability is present in versions 19.0, 19.1.0, 19.1.1, and 19.2.0 of: react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack
- Some React frameworks and bundlers depended on, had peer dependencies for, or included the vulnerable React packages. The following React frameworks & bundlers are affected: next, react-router, waku, @parcel/rsc, @vitejs/plugin-rsc, and rwsdk.
https://github.com/vercel/next.js/compare/v15.0.4...v15.0.5
It looks like the fix is checking hasOwnProperty, so it's almost certainly an issue with prototype chain pollution.
The default react / nextjs configurations being vulnerable to RCE is pretty insane. I think platform level protections from Vercel / Cloudflare are very much showing their utility now!
However, I was curious to see if github copilot can reverse engineer it based on the latest commits and seems that what it is saying aligns with both advisories. It pointed out that it has to do with circular reference handling which sounds to me something that can be easily overlooked.
While this analysis might be completely off, the simple fact that I could get even this information without much efforts is mind-boggling. With better setup it might be able to get more.
With AI now being common place, coordinated timely disclosure is even more important considering the stakes. It is theoretically possible to get an exploit working within minutes. Considering that we see one of these major vulnerabilities annually (and it seems to me around the same time of the year) a bad actor can easily capitalise on the opportunities when presented.
https://news.ycombinator.com/newsguidelines.html
Original non-vendor-hype source: https://react.dev/blog/2025/12/03/critical-security-vulnerab...
Vulnerabilities caused by shoddy JS are a lot more impactful to a server since multiple users will be served by the same runtime instance.
They'll fix it, and it will probably be fine. But every single old school PHP developer and or developer with commonsense knew this was coming.
There was a TC39 proposal a few years ago [0] that proposed to block the getting/setting of object prototypes using the bracket notation, which would have prevented this vulnerability.
At the moment, every single get/set with a square bracket, which uses untrusted data, needs to do some manual check to see whether variables contain "bad" keys like `__proto__`, `prototype,` `constructor`, and so on. This is incredibly annoying, and doesn't really fix the issue. It's possible also to freeze an object's prototype, but that causes other issues. It's also possible to use Object.create(null), and Object.hasOwn (also known as Object.prototype.hasOwnProperty), but again, this does not scale because it has to be done _every single time_.
Maybe it's time to revisit this from a language perspective, instead of continuous bandaid fixes for this language-specific vulnerability (a similar language-specific vulnerability exists in Python called class pollution, but it's .. extremely uncommon).
[0]: https://github.com/tc39/proposal-symbol-proto
RCE Vulnerability in React and Next.js
https://news.ycombinator.com/item?id=46136026