RCE Vulnerability in React and Next.js
Posted by rayhaanj 6 days ago
Comments
Comment by coffeecoders 6 days ago
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.
Comment by tshaddox 6 days ago
Comment by jacquesm 6 days ago
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.
Comment by sysguest 6 days ago
I always felt server-action had too much "magic"
Comment by delifue 6 days ago
Comment by sophiebits 6 days ago
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.)
Comment by cluckindan 6 days ago
Comment by sysguest 6 days ago
am I also vulnerable??????
Comment by cluckindan 6 days ago
Comment by __jonas 6 days ago
Comment by brown9-2 6 days ago
Comment by cluckindan 6 days ago
Comment by dizlexic 6 days ago
Comment by rvnx 6 days ago
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"
Comment by jacquesm 6 days ago
Comment by febusravenga 6 days ago
Comment by sysguest 6 days ago
maybe you should get some sleep
Comment by jacquesm 6 days ago
Comment by j45 6 days ago
Building a private, out of date repo doesn't seem great either.
Comment by coffeecoders 6 days ago
The problem is this specific "call whatever server code the client asks" pattern. Traditional APIs with defined endpoints don’t have that issue.
Comment by j45 6 days ago
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?
Comment by IgorPartola 6 days ago
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.
Comment by alisonkisk 3 days ago
Comment by koakuma-chan 6 days ago
Comment by lionkor 6 days ago
Comment by koakuma-chan 5 days ago
Comment by amluto 5 days ago
JS/Node can do this via import() or require().
C, C++, Go, etc can dynamically load plugins, and I would hope that people are careful when doing this when client-supplied data. There is a long history of vulnerabilities when dlopen and dlfcn are used unwisely, and Windows’s LoadLibrary has historical design errors that made it almost impossible to use safely.
Java finds code by name when deserializing objects, and Android has been pwned over and over as a result. Apple did the same thing in ObjC with similar results.
The moral is simple: NEVER use a language’s native module loader to load a module or call a function when the module name or function name comes from an untrusted source, regardless of how well you think you’ve sanitized it. ALWAYS use an explicit configuration that maps client inputs to code that it is permissible to load and call. The actual thing that is dynamically loaded should be a string literal or similar.
I have a boring Python server I’ve maintained for years. It routes requests to modules, and the core is an extremely boring map from route name to the module that gets loaded and the function that gets called.
Comment by j45 6 days ago
Comment by morshu9001 6 days ago
Comment by j45 5 days ago
Comment by morshu9001 5 days ago
Comment by cluckindan 6 days ago
Comment by Copenjin 6 days ago
If I had a dollar for every time a serious vulnerability that started like this was discovered in the last 30 years...
Comment by nextaccountic 6 days ago
> 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.
Now I'm worried, but I don't use React. So I will have to ask: how does SvelteKit fares in this aspect?
Comment by moralestapia 5 days ago
The vast majority of developers do not update their frameworks to the latest version so this is something that will linger on for years. Particularly if you're on Next something-like-12 and there's breaking changes in order to go to 16 + patch.
OTOH this is great news for bad actors and pentesters.
Comment by danabramov 5 days ago
Comment by jcmontx 6 days ago
Comment by testjag 5 days ago
Comment by ggghjjj 5 days ago
console.log("jsjs")
}Comment by ggghjjj 5 days ago
Comment by isqueiros 6 days ago
i've been thinking basically this for so long, i'm kinda happy to be validated about this lol
Comment by embedding-shape 6 days ago
> 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.
Comment by filearts 6 days ago
Comment by harrall 6 days ago
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.
Comment by int_19h 6 days ago
Comment by ectospheno 4 days ago
Comment by mary-ext 6 days ago
the one problem I haven't understood is how it manages to perform a second call afterwards, as only being able to call Function constructor doesn't really amount to much (still a serious problem though)
Comment by mirashii 6 days ago
Comment by morshu9001 6 days ago
Intentionally? That's a scary feature
Comment by azangru 6 days ago
It's RPC. Remote procedure calls. An approach that has made a comeback in the front-end space recently. There was tRPC; then react made a splash with the release of its server components; then other frameworks started emulating the approach. I think Svelte now has something similar with its "remote functions". And Solid has been working on something similar; so that SolidStart now has a "use server" pragma. They probably don't replicate React's protocol; but the idea of calling functions on the server is similar.
Comment by throwup238 6 days ago
It wasn’t really a “comeback,” RPC never lost popularity. We just called them “REST” APIs that were a barely disguised adhoc JSON RPC format with a few CRUD verbs tacked on for routing requests.
Comment by morshu9001 5 days ago
Comment by morshu9001 5 days ago
Comment by pas 6 days ago
whatever monstrosity hides underneath these nice high-level TypeScript frameworks to make all of it happen in JS, usually that's the worrying part
Comment by halflife 6 days ago
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.
Comment by danabramov 6 days ago
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.
Comment by halflife 6 days ago
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.
Comment by mexicocitinluez 6 days ago
I've literally never heard someone say "React is just a JS framework". They've said React uses JSX over templates. And that React has introduced functional components. But never heard someone say what you're claiming.
> 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.
This is wild. Yes you can. You can write regular JS in components. I can go build a component right now that uses JS (either with or without hooks). You're conflating the rules of hooks with the ability to use Javascript. Yes, there are rules. No, that doesn't mean you can no longer can write JS.
> i18n, angular has the translations compiled into the application and fetching a massive json with translations is not needed
Tradeoffs. Now each update needs to be rebuilt and redeployed. I don't have that problem in React.
> better templating ability for control flows
Better templating? React uses JSX. Are you saying there exists a better way to control flows than if/else?
> signals, for proper reactive state
This has been debated ad-nauseum in the React community and everything has a trade-off. I wish people would stop saying this as if it's categorically correct. React is UI is a function of state. Singlars would totally break the current mental model of React. Data flows down. This change would come with tradeoffs.
Comment by halflife 5 days ago
Of course you CAN write anything you want inside a component, but then it breaks, or has awful performance. To write components the proper way you can’t use any control flows with state management, you need to keep remembering which are the correct dependencies to recreate state, it makes components 20% BL and 80% react logic.
You can’t use if-else in JSX, since only expressions are allowed. So you need to create nested ternaries, which are hard to read, or using JS anomalies like having a condition expression return the last truthish evaluation.
And regarding signals, preact is using it and it doesn’t seem to break anything there.
Function of a state has a nice ring to it, but eventually this was solved a long time before react, every templating engine is a function of a state. The hard part is composing the state easily which react has never been able to achieve.
Comment by anthonylevine 5 days ago
This is still true. I don't currently use any of those things. And the existance of a compiler does imply you can't write Javascript. Totally different concepts. Also, pretty sure they had compiler plans for like years now.
> but then it breaks, or has awful performance.
You're gonna have to be more specific. I could repeat that sentence for every programming language/library on the planet and without specifics it would make sense.
> You can’t use if-else in JSX,
I don't need to use if-else in JSX to control flow. I can write if(condition) return html;
> which are hard to read, or using JS anomalies like having a condition expression return the last truthish evaluation.
See the sentence I just wrote before this. I can use if/else to control flow and return early without templating. How is that not ideal?
> And regarding signals, preact is using it and it doesn’t seem to break anything there.
It's not about literlaly "breaking" something. They could implement htem if they wanted to. It's about breaking the mental model.
In React, data flows down. That's a constraint, but not always a bad one. I know exactly where to look for data (up). With signals, that's throw out the window. And now, it's not just about what the component accepts via props/context (which again, is down) it now needs to turn itself on it's head.
I used Angular for years before React and I do not miss having things talking to each other throw multiple lateral levels.
> Function of a state has a nice ring to it, but eventually this was solved a long time before react, every templating engine is a function of a state.
> Function of a state has a nice ring to it, but eventually this was solved a long time before react, every templating engine is a function of a state. The hard part is composing the state easily which react has never been able to achieve.
This is incredibly misleading (and wrong). Templates don't compose. And React is quite literlaly the king of composition.
It's starting to feel like you've never actually used React, but instead are basing your opinions on what you see other people say (who have also not used React).
Comment by IgorPartola 6 days ago
Comment by fabioborellini 6 days ago
We'll see if the magic can be trusted on or if we need more explicit solutions to this, but the Next/RSC experience was vastly superior compared to writing another REST API that is never to be used with anything else than the accompanied React app, and I'd love to use it or something similar to it in the future.
The reason is probably that a REST API for a "BFF" is in many cases quite tightly coupled with the frontend, and trying to detach those in the system architecture does not separate them in some higher scheme of things. Even if the two parts could separated but would never end up used without another, the separation probably just makes an unnecessary barrier.
Comment by fabioborellini 6 days ago
Comment by rand17 6 days ago
Comment by pimterry 6 days ago
I really do want a good frontend framework that lets me expressively build and render dynamic frontend components, but it feels like 99% of React's development in the last few years has been just been creating churn and making that core frontend experience worse and worse. Hooks solve challenges around sharing component meta-functionality but then end up far worse for all other non-trivial cases, and it seems like RSC & concurrency just break things and add constraints instead of improving any part of my existing experience.
I guess this is cool if you're building mega-projects, but it makes React actively painful to use for anything smaller. I still use it every day, but as soon as I find a good off-ramp for my product (something similar, but simpler) I will take it. Moving towards Preact & signals currently seems like the best option for existing projects so far as I can tell.
Comment by paulhebert 6 days ago
I agree that the developer experience provided by the compiler model used in Svelte and React is much nicer to work with
Comment by halflife 6 days ago
And what they DO add? Only things that improve dev exp
Comment by azangru 6 days ago
The 1 to 2 transition was one hell of a burn though; people are probably still smarting...
Comment by bartread 6 days ago
I’d pushed Angular over React[0] for a massive project, and it worked well, but the migration to Angular 2 when it came created a huge amount of non-value-adding work.
Never again.
I don’t even really want to build anything against Gemini, despite how good it is, because I don’t trust Google not to do another rug pull.
[0] I’ve never enjoyed JSX/TSX syntax, nor appreciated the mix of markup with code, but I’ve subsequently learned to live with it.
Comment by pas 6 days ago
React also went through a lot of churn. (Still does.) There's no magic optimal duration for keeping API stability. Not in general and not for specific projects.
Ecosystems sometimes undergo a phase-shift. Sometimes they take a long time, based on the size. Python 3 was released in 2008, just a year before Angular 1. And the last Py2 release was in 2020, about 2-3 years before the last AngularJS version. (And of course there are many businesses running on py2 still. I know at least one.) These things take plenty of time.
Angular1 was pretty opinionated, willing to break with the tradition of just add one more jQuery plugin.
Miško was working at Google, he persuaded some people to take a look at the framework that he and Adam Abrons were tinkering with.
Angular 2 was announced in 2014 January. And then v1 still got years of support, even the component architecture was "backported" around 1.5 (in 2016?)
You can run old v1 code side-by-side in a v2+ app up until v17. (At least the v17 docs describe the process in full and later docs link to this page. https://v17.angular.io/guide/upgrade )
...
Google did a pretty good job IMHO. Google throws products under the bus, but not so much OSS projects. (Though the sate of AOSP comes to mind.)
Comment by azangru 5 days ago
It abandoned the Material Design web components project, which, I think, attracted some Polymer people.
Speaking of Polymer, it has evolved into Lit; but I understand there is no more support for that project from Google. Lit has joined the OpenJS foundation to stay afloat. The Googlers that used to work on Lit, and on Material Design web components have mostly left.
Also, remember the Workbox project? A simple setup for service workers? It's barely alive.
Comment by halflife 5 days ago
Comment by bartread 5 days ago
I mean, I don't really like TypeScript, and I never have. It's ugly, boilerplatey, and inelegant. I am not a fan.
So... no.
But, again, some battles you have to accept you've lost. TS is everywhere and there's not much getting away from it.
Comment by morshu9001 5 days ago
Comment by bartread 4 days ago
Comment by morshu9001 3 days ago
Comment by altbdoor 6 days ago
Having both old and new Angular running in one project is super weird, but everything worked out in the end.
Comment by halflife 6 days ago
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
Comment by azangru 6 days ago
Angular.js and angular. That's not confusing at all :-)
Comment by sysguest 6 days ago
should be more different: eg "rect-angular vs angular"
Comment by yearolinuxdsktp 6 days ago
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.
Comment by azangru 6 days ago
Lit is pretty good :-) Though it was never positioned as a framework. And it recently was liberated from google.
Comment by morshu9001 6 days ago
Comment by bdangubic 6 days ago
Comment by morshu9001 5 days ago
Comment by symaxian 6 days ago
Comment by morshu9001 5 days ago
Comment by odie5533 6 days ago
Comment by paulhebert 5 days ago
There are lots of things in life that may be “good enough.”
I prefer the things that are better than that
Comment by Kinrany 6 days ago
Comment by morshu9001 6 days ago
Comment by apatheticonion 6 days ago
IMO, a big part of it is the lack of competition (in approach) exacerbated by the inability to provide alternatives due to technical/syntactical limitations of JavaScript itself.
Vue, Svelte, Angular, Ripple - anything other than React-y JSX based frameworks require custom compilers, custom file-types and custom LSPs/extensions to work with.
React/JSX frameworks have preferential treatment with pre-processors essentially baking in a crude compile time macro for JSX transformations.
Rust solved this by having a macro system that facilitated language expansion without external pre-processors - e.g. Yew and Leptos implement Vue-like and React-like patterns, including support for JSX and HTML templating natively inside standard .rs files, with standard testing tools and standard LSP support;
https://github.com/leptos-rs/leptos/blob/main/examples/count...
https://github.com/yewstack/yew/blob/master/examples/counter...
So either the ECMAScript folks figure out a way to have standardized runtime & compilable userland language extensions (e.g. macros) or WASM paves the way for languages better suited to the task to take over.
Neither of these cases are likely, however, so the web world is likely destined to remain unergonomic, overly complex and slow - at least for the next 5 - 10 years.
Comment by morshu9001 6 days ago
Comment by apatheticonion 6 days ago
Frameworks that go that route typically activate this toolchain by defining a dedicated file extension (.vue, .svelte).
This custom toolchain (LSP, IDE plugins) presents a lot of overhead to project maintainers and makes it difficult to actually create a viable alternative to the JSX based ecosystem.
For instance both Vue and Svelte took years to support TypeScript, and their integrations were brittle and often incompatible with test tooling.
Angular used decorators in a very similar way to what I am describing here. It's a source code annotation in "valid" ecmascript that is compiled away by their custom compiler. Though decorators are now abandoned and Angular still requires a lot of custom tooling to work (e.g, try to build an Angular project with a custom rspack configuration).
JSX/TSX has preferential treatment in this regard as it's a macro that's built into tsc - no other framework has this advantage.
Comment by halapro 6 days ago
Comment by morshu9001 5 days ago
Comment by harrall 6 days ago
In my opinion, the core functionality of React (view rendering) is actually good and is why it cannot be unseated.
I remember looking for a DOM library:
- dojo: not for me
- prototype.js: not for me
- MooTools: not for me
- jQuery: something I liked finally
Well, guess what library won. After I adopted jQuery, I completely stopped looking for other DOM libraries.
But I still needed a template rendering library:
- Mustache.js: not for me
- Handlebars.js: not for me
- Embedded JavaScript Templates: not for me
- XML with XSLT: not for me
- AngularJS: really disliked it SOO much*
- Knockout.js: not for me
- Backbone.js with template engine: not for me and actually it was getting popular and I really wished it would just go away at the time**
- React: something I actually liked
You must remember that when React came out, you needed a JSX transpiler too, at a time when few people even used transpilers. This was a far bigger obstacle than these days IMO.
Which leads to my hot take: core React is just really good. I really like writing core React/JSX code and I think most people do too. If someone wrote a better React, I don’t think the problem you mentioned would hamper adoption.
The problems come when you leave React’s core competency. Its state management has never been great. Although not a React project itself, I hated Redux (from just reading its docs). I think RSC at the current moment is a disaster — so many pain points.
I think that’s where we are going to see the next innovation. I don’t think anyone is going to unseat React or JSX itself for rendering templates. No one unseated jQuery for DOM manipulation — rather we just moved entirely away from DOM manipulation.
*I spent 30 minutes learning AngularJS and then decided “I’m never going to want to see this library again.” Lo and behold they abandoned their entire approach and rewrote Angular for v2 so I guess I was right.
**It went away and thankfully I avoided having to ever learn Backbone.js.
Comment by csomar 6 days ago
Comment by paularmstrong 6 days ago
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)
Comment by halflife 6 days ago
Comment by cluckindan 6 days ago
Ultimately that so-called ”isomorphism” causes more numerous and difficult problems than it solves.
Comment by samdoesnothing 6 days ago
Comment by halflife 6 days ago
A purist approach with short term thinking got everyone deep in a rabbit hole with too many pitfalls.
Comment by benignslime 6 days ago
Comment by zackmorris 6 days ago
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.
Comment by baobun 6 days ago
I'm not sure what this is a reference to? Is it actually about Rails?
Comment by zackmorris 5 days ago
I come from a C++ background and mostly use PHP/Laravel today, and even though it does things less "efficiently" than the syntactic sugar in Ruby or low-level optimizations in .NET, I find that its lack of magic makes for much higher productivity in the long run. IMHO it feels like Ruby solves the easiest problems with sugar and then glosses over the hardest problems like they don't exist. So I just can't tell what problems it actually solves.
Generally, I think that cleverness was popular in the 2010s but has fallen out of fashion. A better pattern IMHO works more like Cordova or scripting in video games, where native plugins or a high-performance engine written in a language like Swift or Rust is driven by a scripting language like Javascript or Lua. Or better yet, driven declaratively by HTML or no-code media files that encode complex behavior like animations.
Of course all of this is going away with AI, and I anticipate atrociously poorly-written codebases that can't be managed by humans anymore. Like we might need pair programming just to take a crack at fixing something if the AI can't. I'm always wrong about this stuff though, so hopefully I'm wrong about this.
Comment by odie5533 6 days ago
Comment by zackmorris 5 days ago
For a bit of context, I come from writing blitters on 8 MHz Mac Plusses, so I have a blind spot around slowness. Basically, that nothing should ever be slow today with GHz computers. So most slowness isn't a conceptual flaw, but an inefficient implementation.
These alternative frameworks are generally small enough that it might be kind of fun to stress test them and contribute some performance improvements. Especially with AI, I really have no excuse anymore.
Edit: after pondering this for 2 seconds, I suspect that it's actually a problem with backend requests. It may have some synchronous behavior (which I want) or layout dependency issues that force it to wait until all responses have arrived before rendering. That's a harder problem, but not insurmountable. Also things like this irk me, because browsers largely solved progressive layout in the 1990s and we seem to have lost that knowledge.
Comment by j-krieger 6 days ago
yea? JSX is much more than templating.
Comment by nedt 5 days ago
Comment by mxmzb 6 days ago
Firebase in this context is just a database and how you poll data on client or server from it. Nonsensical reference again.
Comment by acemarke 5 days ago
Redux is still by far the most widely-used state management library in React apps. Some of that _is_ legacy usage, sure. But, our modern Redux Toolkit package has ~30M downloads a month. Zustand has become very popular as a client-side state option, and React Query is now the default standard data fetching tool, but you can see that even just RTK is still right up there in monthly NPM downloads:
- https://npm-stat.com/charts.html?package=redux&package=%40re...
I've frequently talked about the original reasons for Redux's creation, which of those are still relevant, and why Redux is still a very valid option to choose even for greenfield projects today:
- https://blog.isquaredsoftware.com/2024/07/presentations-why-...
Comment by halapro 6 days ago
Comment by TZubiri 6 days ago
It works out because it keeps a workforce of React Developers on their feet, learning about the new features, rather than doing other stuff. It's like SaSS for developers, only instead of paying a monthly subscription in cash, you have to pay a monthly subscription in man-hours.
Comment by benmmurphy 6 days ago
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);Comment by hackhomelab 6 days ago
Comment by nine_k 6 days ago
Comment by karimf 6 days ago
https://vercel.com/changelog/cve-2025-55182
> Cloudflare WAF proactively protects against React vulnerability
Comment by Rauchg 6 days ago
We still strongly recommend everyone to upgrade their Next, React, and other React meta-frameworks (peer)dependencies immediately.
Comment by vanwal_j 5 days ago
I genuinely believe Next.JS is a great framework, but as an European developer working on software that should not touch anything related to CLOUD Act you're just telling me that Next.JS and React, despite being OSS, is not made for me anymore.
Comment by bfelbo 5 days ago
Comment by semiquaver 6 days ago
Comment by odie5533 6 days ago
Comment by serhalp 6 days ago
and Deno Deploy/Subhosting: https://deno.com/blog/react-server-functions-rce
Comment by Jnr 6 days ago
Comment by AgentK20 6 days ago
Comment by nine_k 6 days ago
> Experimental React Flight bindings for DOM using Webpack.
> Use it at your own risk.
311,955 weekly downloads though :-|
Comment by ascorbic 6 days ago
Comment by root_axis 6 days ago
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.
Comment by korm 6 days ago
Comment by swyx 6 days ago
Comment by FINDarkside 6 days ago
Comment by odie5533 6 days ago
Comment by j45 6 days ago
Comment by jeroenhd 6 days ago
While scores are a good way to bring this stuff to people's attention, I wouldn't use them to enforce business processes. There's a good chance your code isn't even affected by this CVE even if your security scanners all go full red alert on this bug.
Comment by j45 5 days ago
Surprised there isn’t more talk about a solution like this or something and more downplaying CVSS.
Downplaying CVSS alone can smell a little like PR talk even however unintentional.
Comment by WatchDog 6 days ago
Comment by j45 6 days ago
The above could be seen as spin too, how could cvss be more accurate so you’d feel better?
Comment by rs_rs_rs_rs_rs 6 days ago
Comment by _jab 6 days ago
Comment by _el1s7 6 days ago
I guess now we'll see more bots scanning websites for "/_next" path rather than "/wp-content".
Comment by ivanjermakov 6 days ago
Comment by jacquesm 6 days ago
Comment by rglover 5 days ago
Comment by jacquesm 5 days ago
https://news.ycombinator.com/item?id=46141771
that is an interesting observation.
Comment by Vinnl 6 days ago
Comment by samdoesnothing 6 days ago
I think their time as Javascript thought leaders is past due.
Comment by zbentley 5 days ago
I’m interested in learning more about the history here.
Comment by samdoesnothing 5 days ago
I believe one of the React email services got pwned because they leaked sensitive info via RSC, and there was a whole fiasco around Next.js encrypting server secrets and sending them to the client.
Lo and behold just a couple years later, a lvl 10 RCE because of the complexity of their RPC approach coupled with the blurring of the lines between client/server...it's not like it's surprising to us. A repro of the vulnerability is on X & Github if you want to search for it, it's a classic deserialization bug that only exists because their format is so complex (and powerful).
Remember a lot of us use React as a UI library and to see it causing our servers to get pwned is what people were uneasy about when they announced RSC.
Unfortunately much of this discussion is on X which makes it hard to find, especially because I think Dan Abromov deleted his X account.
Comment by ejpir 6 days ago
Comment by orkj 6 days ago
However, if I am reading this correctly, your PoC falls in the category described here: https://react2shell.com/
> Anything that requires the developer to have explicitly exposed dangerous functionality to the client is not a valid PoC. Common examples we've seen in supposed "PoCs" are vm#runInThisContext, child_process#exec, and fs#writeFile.
> This would only be exploitable if you had consciously chosen to let clients invoke these, which would be dangerous no matter what. The genuine vulnerability does not have this constraint. In Next.js, the list of server functions is managed for you, and does not contain these.
Context: This is from Lachlan Davidson, the reporter of the vulnerability
Comment by WatchDog 6 days ago
So I don't think this mechanism is exactly correct, can you demo it with an actual nextjs project, instead of your mock server?
Comment by ejpir 6 days ago
1. npm start 2. npm run exploit
Comment by ejpir 6 days ago
I'm debugging it currently, maybe I'm not on the right path after all.
Comment by lionkor 6 days ago
Comment by slopfighter 6 days ago
Comment by jondwillis 6 days ago
Comment by croemer 6 days ago
Comment by croemer 6 days ago
Comment by slop-cop 6 days ago
Delete this distraction to genuine blue teamers and stop shitting up the information landscape with this utter hogwash.
This is why infosec is dead.
https://github.com/ejpir/CVE-2025-55182-poc/issues/1#issueco...
Comment by phelm 6 days ago
Comment by ksherlock 6 days ago
Comment by croemer 6 days ago
Comment by dzonga 6 days ago
mind you react in 2017 paid my rent. now cz of the complexity I refuse to work with react.
Comment by leptons 6 days ago
What do you like to work with now?
Comment by TranquilMarmot 6 days ago
Comment by ethanwillis 6 days ago
They don't address the exact same markets.
Comment by chatmasta 6 days ago
Comment by bdangubic 6 days ago
Comment by chatmasta 6 days ago
htmx is a a toy, mildly amusing to play with, built on an insecure foundation that bypasses basic browser security controls and hands a blob of JavaScript to a bunch of backend developers who can’t be bothered to learn it because they think they know better…
No serious project uses htmx and none ever will, because it becomes an unmaintainable mess by the third developer and second year of development.
Comment by bdangubic 6 days ago
Comment by switz 6 days ago
It's totally fine to say you don't understand why they have benefits, but it really irks me when people exclaim they have no value or exist just for complexity's sake. There's no system for web development that provides the developer with more grounded flexibility than RSCs. I wrote a blog post about this[0].
To answer your question, htmx solves this by leaning on the server immensely. It doesn't provide a complete client-side framework when you need it. RSCs allow both the server and the client to co-exist, simply composing between the two while maintaining the full power of each.
[0] https://saewitz.com/server-components-give-you-optionality
Comment by ptx 6 days ago
Comment by paulhebert 6 days ago
You can create clean separation in your code to make this easier to understand but it’s not well enforced by default.
Comment by samdoesnothing 6 days ago
The criticism is that by allowing you to do something you shouldn't, there isn't any benefit to be had, even if that system allows you to do something you couldn't before.
Comment by lobito25 3 days ago
Comment by AstroBen 6 days ago
I mean it's a lot of complexity but ideally you shouldn't bring it in unless you actually need it. These solutions do solve real problems. The only issue is people try to use it everywhere. I don't use RSC, standard SPAs are fine for my projects and simpler
Comment by venturecruelty 6 days ago
Comment by nonethewiser 6 days ago
Comment by karel-3d 6 days ago
Comment by bitbasher 6 days ago
Comment by division_by_0 6 days ago
> Even in systems that prevent server functions from being declared in client code (such as "use server" in React Server Components), experienced developers can be caught out. We prefer a design that emphasises the public nature of remote functions rather than the fact that they run on the server, and avoids any confusion around lexical scope. [0]
Comment by beders 6 days ago
Comment by dizlexic 6 days ago
Comment by bossyTeacher 6 days ago
Comment by javaking 6 days ago
Comment by jazzypants 6 days ago
> In remote procedure call systems, client-side stub code must be generated and linked into a client before a remote procedure call can be done. This code may be either statically linked into the client or linked in at run-time via dynamic linking with libraries available locally or over a network file system. In either the case of static or dynamic linking, the specific code to handle an RPC must be available to the client machine in compiled form... Dynamic stub loading is used only when code for a needed stub is not already available. The argument and return types specified in the remote interfaces are made available using the same mechanism. Loading arbitrary classes into clients or servers presents a potential security problem;
https://pdos.csail.mit.edu/archive/6.824-2009/papers/waldo-r...
Comment by mvdtnz 6 days ago
Comment by mexicocitinluez 6 days ago
First, "same code on the client and the serve" is wrong. Since when do RSC's run on both the client and the server?
Also, you honestly believe that wanting to use the same language across paradigms is a "coding bootcamp" thing lol? That something like Blazor was born out of a coding bootcamp?
Have you ever built a web app? Both front and back end? Have you ever had to deal with the tension of duplicating code? Models, validation, ideas?
If you answered yes to those questions but still don't see how de-duplicating code like that can be important, than I'm 100% positive you're still in the boot camp.
Comment by chasd00 6 days ago
Comment by homebrewer 6 days ago
Those who don't learn history are bound to repeat it, and all that.
Comment by venturecruelty 6 days ago
Comment by jacquesm 6 days ago
If instead, we would have gradually expanded the HTML standard without adding a fully functional programming language into the content stream we would have had better consistency between websites and applications and we would treat the browser like what it is: a content delivery mechanism, not an application programming platform. That's the core mistake as far as I'm concerned.
Comment by c-hendricks 6 days ago
Comment by serhalp 6 days ago
To be fair, they also haven't released (even experimental) RSC support yet, so maybe they lucked out on timing here.
Comment by dimitrisnl 6 days ago
Comment by auggierose 6 days ago
Comment by Raicuparta 6 days ago
Comment by vinnymac 6 days ago
I have built electron apps for fun that utilize React Server Components entirely offline.
Comment by ajross 6 days ago
Comment by heisenbit 6 days ago
Comment by padjo 6 days ago
Comment by ajross 6 days ago
Basically you're technically correct with your quip, but engaging in some pretty awful security analysis. IMHO most people reading this headline are not going to understand that they need to audit their server dependencies.
Comment by dfedbeef 6 days ago
Comment by IceDane 6 days ago
Comment by oliverpk 5 days ago
Comment by darepublic 6 days ago
Comment by udev4096 6 days ago
Comment by testjag 5 days ago
Comment by heldrida 6 days ago
Comment by henryfjordan 6 days ago
With SSR, those round trips to the server could be down to single-digit milliseconds assuming your frontend server is in the same datacenter as your backend. Plus you send HTML that has actual content to be rendered right away.
A truly functional pageload can go from seconds to milliseconds, and you're transferring less data over the wire. Better all around at the expense of running a React Server instead of a static file host.
Comment by jazzypants 6 days ago
Comment by quentindanjou 6 days ago
SSR can be a game-changer in domains like e-commerce. But completely useless for some other use case.
RSC advantages are a bit more complex to explain, because even a simple portfolio website would benefit from it. Contrary to the common belief created by long-term ReactJS dev, RSC simplifies a lot of the logic. Adapting existing code to RSC can be quite a mess and RSC is a big change of mindset for anybody used to ReactJS.
Comment by venturecruelty 6 days ago
Comment by Levitating 6 days ago
Comment by jeroenhd 6 days ago
Comment by jacquesm 6 days ago
Comment by gloosx 6 days ago
Comment by z3ratul163071 6 days ago
Comment by Tomuus 6 days ago
Comment by steve_adams_86 5 days ago
Comment by antonstihl 6 days ago
Comment by fergie 6 days ago
Comment by darig 6 days ago
Comment by cowsandmilk 6 days ago
Comment by Tomuus 6 days ago
Comment by cluckindan 6 days ago
Comment by slop-cop 6 days ago
Delete this distraction to genuine blue teamers and stop shitting up the information landscape with this utter hogwash.
This is why infosec is dead.
https://github.com/ejpir/CVE-2025-55182-poc/issues/1#issueco...
Comment by Copenjin 6 days ago
Comment by gcau 6 days ago
Comment by kachapopopow 6 days ago
Comment by sylware 6 days ago
Comment by nickthegreek 6 days ago
Comment by anonymars 6 days ago
Comment by dacodaco1 4 days ago
Comment by dacodaco1 4 days ago
Comment by mohamed_altyb 6 days ago
Comment by dizlexic 6 days ago
Comment by cluckindan 6 days ago
Comment by ptx 6 days ago
> a flaw in how React decodes payloads sent to React Server Function endpoints
and the react.dev docs for React Server Functions [2] say that
> Server Components can define Server Functions with the "use server" directive [...] Client Components can import Server Functions from files that use the "use server" directive
So it certainly sounds like the vulnerability is related to React Server Functions which are related to "use server".
[1] https://react.dev/blog/2025/12/03/critical-security-vulnerab...
Comment by cluckindan 6 days ago
Comment by dizlexic 6 days ago
That seems like it could be a quote from their hardening guide.
Comment by ptx 6 days ago
Comment by jazzypants 6 days ago
Comment by vinnymac 6 days ago
> Even if your app does not implement any React Server Function endpoints it may still be vulnerable if your app supports React Server Components.
Comment by jazzypants 5 days ago
Comment by spoctrial 6 days ago
Comment by danabramov 5 days ago
Comment by ashishb 6 days ago
Those who are choosing JS for the backend are irresponsible stewards of their customers' data.
Comment by tills13 6 days ago
Comment by odie5533 6 days ago
Comment by ashishb 6 days ago
Even if that's true, it is irrelevant.
- You need to decide package manager and everyone has their favorite one: npm, yarn, bun, pnpm ...
- You need to depend on npmjs.com for dependencies, which has an unusually high number of malicious packages compared to other dependency sources.
- You need to use some framework like Next.js, which itself is a cesspool of backward-incompatible changes, combined with outrageous security issuesComment by steve_adams_86 5 days ago
Arguably the safest approach is to embed all dependencies in your source, and vet all of them for each release. But I'm glad deno lets me choose which registry I use.
Bun also allows for this but it feels a bit more tacked-on and less like an early architectural decision based around security concerns.
Comment by ashishb 5 days ago
How would Deno have prevented the RCE issue with React+Next.js?
Comment by steve_adams_86 5 days ago
You avoid the RCE by recognizing that React—and more recently Vercel's—management is a bit of a tire fire, and you should choose better tools with more responsible maintainers.
Part of what bothers me about this situation is that React appears to be a view library, and to many people using it that is what it functions as... But it's now a framework which extends well beyond the browser and entails all kinds of security risks that aren't intuitive at a glance, at all. A lot of people using Next probably have no idea about the security implications of the framework or how React fits into them. It's a mess.
Deno definitely can't fix that.
Comment by int_19h 6 days ago