Top
Best
New

Posted by rayhaanj 9 hours ago

RCE Vulnerability in React and Next.js(github.com)
389 points | 120 comments
coffeecoders 6 hours ago|
This vulnerability is basically the worst-case version of what people have been warning about since RSC/server actions were introduced.

The server was deserializing untrusted input from the client directly into module+export name lookups, and then invoking whatever the client asked for (without verifying that metadata.name was an own property).

    return moduleExports[metadata.name]

We can patch hasOwnProperty and tighten the deserializer, but there is deeper issue. React never really acknowledged that it was building an RPC layer. If you look at actual RPC frameworks like gPRC or even old school SOAP, they all start with schemas, explicit service definitions and a bunch of tooling to prevent boundary confusion. React went the opposite way: the API surface is whatever your bundler can see, and the endpoint is whatever the client asks for.

My guess is this won't be the last time we see security fallout from that design choice. Not because React is sloppy, but because it’s trying to solve a problem category that traditionally requires explicitness, not magic.

tshaddox 1 hour ago||
To me it just looks like unacceptable carelessness, not an indictment of the alleged "lack of explicitness" versus something like gRPC. Explicit schemas aren't going to help you if you're so careless that, right at the last moment, you allow untrusted user input to reference anything whatsoever in the server's name space.
jacquesm 22 minutes ago||
But once that particular design decision is made it is a question of time before that happens. The one enables the other.

The fact that React embodies an RPC scheme in disguise is quite obvious if you look at the kind of functionality that is implemented, some of that simply can not be done any other way. But then you should own that decision and add all of the safeguards that such a mechanism requires, you can't bolt those on after the fact.

sophiebits 5 hours ago|||
The endpoint is not whatever the client asks for. It's marked specifically as exposed to the user with "use server". Of course the people who designed this recognize that this is designing an RPC system.

A similar bug could be introduced in the implementation of other RPC systems too. It's not entirely specific to this design.

(I contribute to React but not really on RSC.)

cluckindan 3 hours ago|||
”use server” is not required for this vulnerability to be exploitable.
brown9-2 3 hours ago|||
so any package could declare some modules as “use server” and they’d be callable, whether the RSC server owner wanted them to or not? That seems less than ideal.
dizlexic 4 hours ago|||
They were warned. I don't see how this can be characterized as anything but sloppy.
rvnx 2 hours ago|||
You can call anything, anytime, anywhere without restrictions or protection.

Imagine these dozens of people, working at Meta.

They sit at the table, they agree to call eval() and not think "what could go wrong"

jacquesm 20 minutes ago||
Eval has been known to be super dangerous since before the internet grew up and went mainstream. It is so dangerous that to deploy stuff containing it should come with a large flashing warning whenever you run it.
j45 6 hours ago||
For the layperson, does this mean this approach and everything that doesn't use it is not secure?

Building a private, out of date repo doesn't seem great either.

coffeecoders 6 hours ago||
Not quite. This isn’t saying React or Next.js are fundamentally insecure in general.

The problem is this specific "call whatever server code the client asks" pattern. Traditional APIs with defined endpoints don’t have that issue.

koakuma-chan 4 hours ago|||
You mean call whatever server action the client asks? I don't think having this vulnerability was intentional.
j45 2 hours ago||
I don’t think I’ve heard of intentional vulnerabilities?
morshu9001 1 hour ago|||
Log4j almost seemed like it
cluckindan 1 hour ago|||
xz?
j45 3 hours ago|||
I’m not asking if it’s fundamentally insecure.

Architecturally there appears to be an increasingly insecure attack surface appearing in JavaScript at large, based on the insecurities in mandatory dependencies.

If the foundation and dependencies of react has vulnerabilities, react will have security issues indirectly and directly.

This explicit issue seems to be a head scratcher. How could something so basic exist for so long?

Again I ask about react and next.js from their perspective or position of leadership in the JavaScript ecosystem. I don’t think this is a standard anyone wants.

Could there be code reviews created for LLMs to search for issues once discovered in code?

IgorPartola 1 hour ago||
To be fair, the huge JavaScript attack surface has ALWAYS been there. JavaScript runs in a really dynamic environment and everything from XSS-onwards has been fundamentally due to why you can do with the environment.

If you remember “mashups” these were basically just using the fact that you can load any code from any remote server and run it alongside your code and code from other servers while sharing credentials between all of them. But hey it is very useful to let Stripe run their stripe.js on your domain. And AdSense. And Mixpanel. And while we are at it let’s let npm install 1000 packages for a single dependency project. It’s bad.

embedding-shape 8 hours ago||
From Facebook/Meta: https://www.facebook.com/security/advisories/cve-2025-55182

> A pre-authentication remote code execution vulnerability exists in React Server Components versions 19.0.0, 19.1.0, 19.1.1, and 19.2.0 including the following packages: react-server-dom-parcel, react-server-dom-turbopack, and react-server-dom-webpack. The vulnerable code unsafely deserializes payloads from HTTP requests to Server Function endpoints.

React's own words: https://react.dev/blog/2025/12/03/critical-security-vulnerab...

> React Server Functions allow a client to call a function on a server. React provides integration points and tools that frameworks and bundlers use to help React code run on both the client and the server. React translates requests on the client into HTTP requests which are forwarded to a server. On the server, React translates the HTTP request into a function call and returns the needed data to the client.

> An unauthenticated attacker could craft a malicious HTTP request to any Server Function endpoint that, when deserialized by React, achieves remote code execution on the server. Further details of the vulnerability will be provided after the rollout of the fix is complete.

filearts 7 hours ago||
Given that the fix appears to be to look for own properties, the attack was likely to reference prototype level module properties or the gift-that-keeps-giving the that is __proto__.
harrall 1 hour ago|||
I see this type of vulnerability all the time. Seen it in Java, Lua, JavaScript, Python and so on.

I think deserialization that relying on blacklists of properties is a dangerous game.

I think rolling your own object deserialization in a library that isn’t fully dedicated to deserialization is about as dangerous as writing your own encryption code.

mirashii 2 hours ago|||
This comment from a dupe thread is worth considering: https://news.ycombinator.com/item?id=46137352
morshu9001 1 hour ago||
"React Server Functions allow a client to call a function on a server"

Intentionally? That's a scary feature

halflife 5 hours ago||
Why does the react development team keeps investing their time on confusing features that only reinvent the wheel and cause more problems than solve?

What does server components do so much better than SSR? What minute performance gain is achieved more than client side rendering?

Why won’t they invest more on solving the developer experience that took a nosedive when hooks were introduced? They finally added a compiler, but instead of going the svelte route of handling the entire state, it only adds memoization?

If I can send a direct message to the react team it would be to abandon all their current plans, and work on allowing users to write native JS control flows in their component logic.

sorry for the rant.

danabramov 5 hours ago||
Server Components is not really related to SSR.

I like to think of Server Components as componentized BFF ("backend for frontend") layer. Each piece of UI has some associated "API" with it (whether REST endpoints, GraphQL, RPC, or what have you). Server Components let you express the dependency between the "backend piece" and the "frontend piece" as an import, instead of as a `fetch` (client calling server) or a <script> (server calling client). You can still have an API layer of course, but this gives you a syntactical way to express that there's a piece of backend that prepares data for this piece of frontend.

This resolves tensions between evolving both sides: the each piece of backend always prepares the exact data the corresponding piece of frontend needs because they're literally bound by a function call (or rather JSX). This also lets you load data as granularly as you want without blocking (very nice when you have a low-latency data layer).

Of course you can still have a traditional REST API if you want. But you can also have UI-specific server computation in the middle. There's inherent tension between the data needed to display the UI (a view model) and the way the data is stored (database model); RSC gives you a place to put UI-specific logic that should execute on the backend but keeps composability benefits of components.

halflife 4 hours ago||
Thanks for the comment Dan, I always appreciate you commenting and explaining in civility, and I’m sorry if I came a bit harsh.

I understand the logic, but there are several issues I can think of.

1 - as I said, SSR and API layers are good enough, so investing heavily in RSC when the hooks development experience is still so lacking seems weird to me. React always hailed itself as the “just JS framework”, but you can’t actually write regular JS in components since hooks have so many rules that bind the developer in a very specific way of writing code.

2 - as react was always celebrated as an unopinionated framework, RSC creates a deep coupling between 2 layers which were classically very far apart.

Here are a list of things that would rather have react provide:

- advanced form functionality that binds to model, and supports validation

- i18n, angular has the translations compiled into the application and fetching a massive json with translations is not needed

- signals, for proper reactive state

- better templating ability for control flows

- native animation library

All of these things are important so I wouldn’t have to learn each new project’s permutation of the libraries de jour.

paulhebert 5 hours ago|||
I wish React wasn’t the “default” framework.

I agree that the developer experience provided by the compiler model used in Svelte and React is much nicer to work with

halflife 5 hours ago||
IMO angular provides such a great experience developing. They had minimal API changes in the last 10 years, and every project looks almost the same since it’s so opinionated.

And what they DO add? Only things that improve dev exp

azangru 3 hours ago||
> They had minimal API changes in the last 10 years

The 1 to 2 transition was one hell of a burn though; people are probably still smarting...

altbdoor 1 hour ago|||
It was one hell of a ride, but I would say the Angular team did one hell of a job too, supporting the glue code until v18 (not sure if the latest version still does).

Having both old and new Angular running in one project is super weird, but everything worked out in the end.

halflife 3 hours ago|||
Well, the official statement is that 1 and 2 are 2 different frameworks. That’s why they were later named to angular JS and angular, to avoid confusion.

The migration path between angular 1 and 2 is the same as react and angular, it’s just glue holding 2 frameworks together

And that change happened 10 years ago

azangru 1 hour ago|||
> That’s why they were later named to angular JS and angular, to avoid confusion.

Angular.js and angular. That's not confusing at all :-)

yearolinuxdsktp 1 hour ago|||
Easy migration was promised but never delivered. Angular 2 was still full of boilerplate. “Migrating” an AngularJS project to Angular 2 is as much work as porting it to React or anything else.

So yes, people got burnt (when we were told that there will be a migration path), and I will never rely on another Google-backed UI framework.

azangru 1 hour ago||
> I will never rely on another Google-backed UI framework.

Lit is pretty good :-) Though it was never positioned as a framework. And it recently was liberated from google.

morshu9001 1 hour ago|||
I like the hooks :(
paularmstrong 5 hours ago|||
> What does server components do so much better than SSR? What minute performance gain is achieved more than client side rendering?

RSC is their solution to not being able to figure out how to make SSR faster and an attempt to reduce client-side bloat (which also failed)

halflife 5 hours ago||
Maybe if they compiled away their runtime like svelte and somewhat like angular, then running SSR would be faster.
cluckindan 3 hours ago||
SSR with CSR is a worst-of-both-worlds approach. It leads to brittle ”isomorphic” behaviors when the same code needs to handle both SSR and CSR, inevitable client-side ”hydration” mismatches and various other issues. The same code needs to fetch eagerly but minimally, but also use and update the server-provided data on the client-side.

Ultimately that so-called ”isomorphism” causes more numerous and difficult problems than it solves.

halflife 3 hours ago|||
Sounds a little like hooks.

A purist approach with short term thinking got everyone deep in a rabbit hole with too many pitfalls.

samdoesnothing 3 hours ago|||
Especially cuz the vast majority of sites can either just be client rendered SPA's or server rendered multipage apps. There is no need for the complexity for most sites and yet this is the default for pretty much all js frameworks...
zackmorris 3 hours ago||
I couldn't agree more. I'll probably switch from React to something like ArrowJS in my personal work:

https://www.arrow-js.com/docs/

It makes it easy to have a central JSON-like state object representing what's on the page, then have components watch that for changes and re-render. That avoids the opaqueness of Redux and promise chains, which can be difficult to examine and debug (unless we add browser extensions for that stuff, which feels like a code smell).

I've also heard heard good things about Astro, which can wrap components written in other frameworks (like React) so that a total rewrite can be avoided:

https://docs.astro.build/en/guides/imports/

I'm way outside my wheelhouse on this as a backend developer, so if anyone knows the actual names of the frameworks I'm trying to remember (hah), please let us know.

IMHO React creates far more problems than it solves:

  - Virtual DOM: just use Facebook's vast budget to fix the browser's DOM so it renders 1000 fps using the GPU, memoization, caching, etc and then add the HTML parsing cruft over that
  - Redux: doesn't actually solve state transfer between backend and frontend like, say, Firebase
  - JSX: do we really need this when Javascript has template literals now?
  - Routing: so much work to make permalinks when file-based URLs already worked fine 30 years ago and the browser was the V in MVC
  - Components: steep learning curve (but why?) and they didn't even bother to implement hooks for class components, instead putting that work onto users, and don't tell us that's hard when packages like react-universal-hooks and react-hookable-component do it
  - Endless browser console warnings about render changing state and other errata: just design a unidirectional data flow that detects infinite loops so that this scenario isn't possible
I'll just stop there. The more I learn about React, the less I like it. That's one of the primary ways that I know that there's no there there when learning new tools. I also had the same experience with the magic convention over configuration in Ruby.

What's really going on here, and what I would like to work on if I ever win the internet lottery (unlikely now with the arrival of AI since app sales will soon plummet along with website traffic) is a distributed logic flow. In other words, a framework where developers write a single thread of execution that doesn't care if it's running on backend or frontend, that handles all state synchronization, preferably favoring a deterministic fork/join runtime like Go over async behavior with promise chains. It would work a bit like a conflict-free replicated data type (CRDT) or software transactional memory (STM) but with full atomicity/consistency/isolation/durability (ACID) compliance. So we could finally get back to writing what looks like backend code in Node.js, PHP/Laravel, whatever, but have it run in the browser too so that users can lose their internet connection and merge conflicts "just work" when they go back online.

Somewhat ironically, I thought that was how Node.js worked before I learned it, where maybe we could wrap portions of the code to have @backend {} or @frontend {} annotations that told it where to run. I never dreamed that it would go through so much handwaving to even allow module imports in the browser!

But instead, it seems that framework maintainers that reached any level of success just pulled up the ladder behind them, doing little or nothing to advance the status quo. Never donating to groups working from first principles. Never rocking the boat by criticizing established norms. Just joining all of the other yes men to spread that gospel of "I've got mine" to the highest financial and political levels.

So much of this feels like having to send developers to the end of the earth to cater to the runtime that I question if it's even programming anymore. It would be like having people write the low-level RTF codewords in MS word rather than just typing documents via WYSIWYG. We seem to have all lost our collective minds ..the emperor has no clothes.

baobun 3 hours ago||
> I also had the same experience with the magic convention over configuration in Ruby.

I'm not sure what this is a reference to? Is it actually about Rails?

benmmurphy 8 hours ago||
I suspect the commit to fix is:

https://github.com/facebook/react/commit/bbed0b0ee64b89353a4...

and it looks like its been squashed with some other stuff to hide it or maybe there are other problems as well.

this pattern appears 4 times and looks like it is reducing the functions that are exposed to the 'whitelist'. i presume the modules have dangerous functions in the prototype chain and clients were able to invoke them.

      -  return moduleExports[metadata.name];
      +  if (hasOwnProperty.call(moduleExports, metadata.name)) {
      +    return moduleExports[metadata.name];
      +  }
      +  return (undefined: any);
hackhomelab 7 hours ago|
It could also be https://github.com/facebook/react/commit/7dc903cd29dac55efb4... ("This also fixes a critical security vulnerability.")
nine_k 7 hours ago||
It does the same thing here, too: https://github.com/facebook/react/commit/7dc903cd29dac55efb4...
ejpir 4 hours ago||
I'm fumbled around a bit and got it working, but not entirely sure if this is how it really works: have a look at https://github.com/ejpir/CVE-2025-55182-poc
WatchDog 34 minutes ago||
I ran your exploit-rce-v4.js with and without the patched react-server-dom-webpack, and both of them executed the RCE.

So I don't think this mechanism is exactly correct, can you demo it with an actual nextjs project, instead of your mock server?

ejpir 21 minutes ago||
I'm trying that, nextjs is a little different because it uses a Proxy object before it passes through, which blocks the rce.

I'm debugging it currently, maybe I'm not on the right path after all.

croemer 2 hours ago||
Thanks for the writeup, it's incredible!
karimf 7 hours ago||
> Projects hosted on Vercel benefit from platform-level protections that already block malicious request patterns associated with this issue.

https://vercel.com/changelog/cve-2025-55182

> Cloudflare WAF proactively protects against React vulnerability

https://blog.cloudflare.com/waf-rules-react-vulnerability/

Rauchg 7 hours ago||
We collaborated with many industry partners to proactively deploy mitigations due to the severity of the issue.

We still strongly recommend everyone to upgrade their Next, React, and other React meta-frameworks (peer)dependencies immediately.

semiquaver 6 hours ago||
Does AWS WAF have a mitigation in place?
serhalp 6 hours ago||
Same for Netlify: https://www.netlify.com/changelog/2025-12-03-react-security-...

and Deno Deploy/Subhosting: https://deno.com/blog/react-server-functions-rce

_el1s7 5 hours ago||
Next.js/RSC has become the new PHP :)

I guess now we'll see more bots scanning websites for "/_next" path rather than "/wp-content".

ivanjermakov 1 hour ago|
Inevitable when the line between the client and the server is blurred this much. RCE in a UI library is not a phrase you hear often.
jacquesm 19 minutes ago||
Maybe one day we'll look back at JavaScript and conclude it was a gigantic mistake ship unaudited executable code to a few billion people every day.
AgentK20 9 hours ago||
CVE 10.0 is bonkers for a project this widely used
nine_k 7 hours ago||
The packages affected, like [1], literally say:

> Experimental React Flight bindings for DOM using Webpack.

> Use it at your own risk.

311,955 weekly downloads though :-|

[1]: https://www.npmjs.com/package/react-server-dom-webpack

ascorbic 7 hours ago||
That number is misleadingly low, because it doesn't include Next.js which bundles the dependency. Almost all usage in the wild will be Next.js, plus a few using the experimental React Router support.
root_axis 5 hours ago||
As far as I'm aware, transitive dependencies are counted in this number. So when you npm install next.js, the download count for everything in its dependency tree gets incremented.

Beyond that, I think there is good reason to believe that the number is inflated due to automated downloads from things like CI pipelines, where hundreds or thousands of downloads might only represent a single instance in the wild.

korm 5 hours ago|||
It's not a transitive dependency, it's just literally bundled into nextjs, I'm guessing to avoid issues with fragile builds.
swyx 3 hours ago|||
why is it not normal for CI pipelines to cache these things? its a huge waste of compute and network.
FINDarkside 3 hours ago||
It's certainly not uncommon to cache deps in CI. But at least at some point CircleCI was so slow at saving+restoring cache that it was actually faster to just download all the deps. Generally speaking for small/medium projects installing all deps is very fast and bandwidth is basically free, so it's natural many projects don't cache any of it.
j45 6 hours ago|||
The subjects of theses types of posts should report the CVSS severity as 10.0 so the PR speak can't simply deflect to what needs to be done.
WatchDog 1 hour ago||
A CVSS score of 10.0 may be warranted in this case, but so many other CVSS scores are wildly inflated, that the scores don't mean a lot.
j45 50 minutes ago||
Regardless it can still provide some context and adjustment cs none.

The above could be seen as spin too, how could cvss be more accurate so you’d feel better?

rs_rs_rs_rs_rs 8 hours ago||
React is widely used, react server components not so much.
_jab 7 hours ago||
Next.js is still pretty damn widely used.
phelm 8 hours ago||
More detail in the React Blog post here https://react.dev/blog/2025/12/03/critical-security-vulnerab...
croemer 7 hours ago|
Link should go to: https://react.dev/blog/2025/12/03/critical-security-vulnerab...
More comments...