Reacts biggest Mistake

The PrimeTime| 00:11:07|May 18, 2026
Chapters8
Discusses the repeated upgrade warnings for Next.js and the security risks tied to not upgrading.

If you’re using React/Next.js, upgrade fast—the video breaks down a real, high-severity server-side vulnerability and why forced upgrades keep happening.

Summary

The PrimeTime’s video dives into the ongoing frenzy around Next.js upgrades and the security implications of React Server Components. With a humorous yet sharp tone, the host walks through a high-severity vulnerability that lets an unauthenticated attacker trigger heavy CPU load and potential DoS via a crafted server action payload. He references public advisories and a “slop repo” full of reproduced exploits to illustrate how deep these issues run, then translates the technical details into what it means for developers working with Next.js app routers and React server components. The discussion shifts from the specifics of the exploit to broader questions about server-side rendering, data fetching, and the practical trade-offs of server components versus traditional client-driven data loading. Throughout, there’s a reminder that even non-Next.js users can be impacted by these vulnerabilities if they rely on React engine behavior in production. The host injects personal anecdotes about past React experiences to underscore learning moments and the perennial tension between innovation and security. Overall, the piece blends technical depth with candid commentary on how upgrade cycles shape engineering decisions and incident response.

Key Takeaways

  • An unauthenticated attacker can exploit a Next.js app router payload to force the server to spin CPU/stack overflow for tens of seconds per request, effectively causing a Denial of Service.
  • Public advisories describe an RCE-like risk tied to React decode reply actions and server action bodies, highlighting how encoded payloads can trigger deep hydration loops.
  • A looped hydration/revival process in the server model can recursively reference objects leading to stack growth; about 53,000 iterations were tested to cause a stack overflow in the example.
  • The vulnerability can be triggered without authentication on older React versions, emphasizing the importance of timely upgrades even for apps not using Next.js specifically.
  • The host questions the core allure of server components, suggesting that data loading and caching strategies could be simpler and often more robust without the added complexity of SSR tricks.
  • HTMX is proposed as an alternative in the discussion, framed as a potentially simpler approach to dynamic content delivery alongside AI-era tooling.
  • The talk blends technical explanation with personal anecdotes to emphasize that rapid upgrades are a reality in modern web development, not just a theoretical concern.

Who Is This For?

Web developers and DevOps teams using React, Next.js, or server components who need to understand upgrade risks, vulnerability exposure, and practical mitigations. It’s especially relevant for those weighing server-side rendering trade-offs and data-fetching strategies.

Notable Quotes

""An unauthenticated attacker can post a form encoded reply body to an app router page with the next action header and force the server to spin CPU/stack overflow for tens of seconds per request.""
Direct description of the exploit mechanism feeding the DoS scenario.
""If you don’t upgrade, you will simply have… a middleware proxy bypass, another denial of service, a server-side request forgery, a cross-site scripting...""
Emphasizes the breadth of vulnerabilities tied to older versions.
""You’re effectively doing a DDoS. You can just send one message and boom your computer… is completely off.""
Illustrates the severity of the looped hydration vulnerability.
""Honestly, there’s quite a few vulnerabilities here, so we are going to take apart the very tippy top one…""
Sets up the focus on the highest-risk issue in the talk.
""I’ve learned very, very, very valuable lessons, which was just say no early on. Just say no.""
Closing personal reflection tying experience to security decisions.

Questions This Video Answers

  • What exactly causes a DoS in Next.js with React server components, and how can I protect my app?
  • How do server actions in Next.js app router work, and what are the associated risks?
  • Should I upgrade React/Next.js immediately if I’m not using server components, and what about older deployments?
  • What is HTMX and how might it compare to React Server Components for dynamic content?
  • How can I safely test for hydration cycles and stack overflows in a React/Next.js project?
React Server ComponentsNext.js app routerServer-side renderingVulnerability disclosureDenial of ServiceRemote code execution riskHTMXAI in development tooling
Full Transcript
Hey, remember this tweet from last December when Next.js said, "Hey everybody, you better upgrade. Uh if you don't, well, there's kind of a remote code execution on pretty much every version of Next.js. So, hey, but server components are really cool though." And of course, everybody upgraded only to be met yet again just a couple days ago. Hey, guess what everybody? You better uh upgrade because well, if you don't upgrade, you will simply have um a denial of a middleware proxy bypass, another a middleware proxy bypass, another denial of service, another middleware proxy bypass, a server-side request forgery, a middleware proxy bypass, a cross-site scripting, a second cross-site scripting, a denial of service, a cache poisoning, a second cache poisoning, or potentially a fifth middleware proxy bypass. Hey, you know what I'm talking about? AI, man. Isn't AI pretty sweet? Like, look at that. You know, like that's AI, bro. That's what we're getting out of this. Hey, honestly, React is more secure now. You just got to upgrade. Either way, I'd like to call myself a bit of a Nostradamus. As a person who's written a data fetching library, let me just tell you, it's really easy to screw it up. Now, obviously, the forced upgrades will continue until morale improves or you finally switch over to using HTMX, which by the way, the lord's library, and it works really well with AI. So, if you're I'm just just throwing that out there, okay? Now, obviously, there's quite a few vulnerabilities here, so we are going to take apart the very tippy top one, the highest one, which is actually a bug that's within React. But before we do that, we got to get the bag. Hey, is that HTTP? Get that out of here. That's not how we order coffee. We order coffee via SSH, terminal.shop. Yeah, you want a real experience? You want real coffee? You want awesome subscription so you never have to remember again? Oh, you want exclusive blends with exclusive coffee and exclusive content? [music] Then check out Chrome. You don't know what SSH is? Well, maybe the coffee's not for you. [singing] [music] Now, there's no information on the actual exploits, at least given out publicly officially, but there is this beautiful slop pository in which has reproduction steps for pretty much every single one of them all listed out nicely. Now, we're going to go to the very tippity top one that I showed you before, and it gives you this beautiful piece of code right here. And if you jump into the YAML, you can actually read what it's about. It's just taken straight from the actual CV website, which is going to say this: Next.js app router consumes React decode reply action bundled from React server DOM webpack to parse React server components replies server action bodies. Pre-patch React walk the reply graph during model resolution without any depth cycle or row count limit. An unauthenticated attacker can post a form encoded reply body to an app router page with the next action header and force the server to spin CPU/stack overflow for tens of seconds per request. In other words, you're effectively doing a DDoS. You're denying the server's ability to process any other request cuz remember, JavaScript. Yo, we're single-threaded, pretty much. As this thing just spins and does nothing, your CPU's pegged and you have pretty much no insights as to what's happening, and you can even get a stack overflow if you provide enough of these encoded items. So, what are these encoded items? Remember I said it was a slop pository? Well, here's part of the example of the slop pository. Inside of this beautiful bash file, we also have some beautiful Python going on right here. I mean, nothing tells me that an AI has written something than code that looks like this. This is This is what makes AI happy, okay? If AI has the ability to be in bash piping out to Python, I mean, it is one happy mythos. Honestly, kind of making Dario proud right now. And so, then it produces this value right here over and over again, and it does this whole next thing right here. So, it says, "Hey, all right. I'm going to create a dollar sign F with a value in hexadecimal, and I'm going to then going to create an object that references this next value also in hexadecimal. Now, you're probably thinking, "Okay, I don't even have any idea what that means." Well, that's not a big deal, because guess what? This isn't our first time inside this code. So, if you go over to this parse model string function, it actually is doing the parsing. Now, remember, in regular user land, typically people from websites send up JSON. Oh, no, no, no, no, no, no. Not in React land. See, in React land, you have your client, right? Big old C client here. Let me increase the size. Oh, and I went down in size. Oh my gosh, embarrassing. Can I say that? Embarrassing. Okay, a little too big, but whatever. Uh your client and your server communicate back and forth. Now, typically in your normal world, probably at your normal job, you're using JSON. So, you can just call like JSON.parse. Better wrap a little try-catch around that, or else your server explodes, but you get the idea. Pretty straightforward. Your client does the exact same thing, but not in React server components land. The special meetings almost always start off as a string. It starts off as a string with a dollar sign. From there, it has some sort of control character, like, "Hey, what kind of action are you actually asking me to perform?" If I remember correctly, it's actually this code right here, a subclass B for blob. This is actually how the previous one had remote code execution is by calling this function right here, which ended up returning a function in which was actually specified as part of the input and being stringified as a function into an actual JavaScript function, which allowed the user just to say, "Hey, here's what I want you to execute. I control the string and you turn it into JavaScript for me and I can do whatever I want on your machine." It was not good, not good at all. But this time, it's an uppercase F. Again, jump right here, you can see the uppercase F, so it's setting something up. And what this does is this says, "Hey, I have a reference. You are referring to some object somewhere on the server, so I'm going to decode it for you." And so it does this get outlined model call right here. Well, outlined model will simply go off and do the hydration, do whatever it needs to do, except if this model has already been resolved once before. Now, this is where this beautiful loop comes in right here because if you look at this, who am I referring to? I'm going to refer to the next one in line unless if we've gone all the way around, then I'm going to make a nice little ring right here, so that way the last element refers to the first element. So when we get here and we've already initialized the model, it's going to call this, "Hey, we need to initialize this chunk." Specifically, so it would actually points to the correct object. Now, inside of initialize model chunk, what it's doing is going to revive the model. I assume this is like the hydration process. Like, "Hey, here's all the stuff that exists on the server, so go off and do it." Now, when you're reviving the model, if the value I passed into you was a string, oh my gosh, it's a string. So it's going to go here and recall parse model, so you can kind of guess what happens here. We parse model to get outlined model to initialize model chunk to revive model to parse model string. And we're just going to keep on doing this nice little circle as much as we can until bad things happen. In fact, it only takes 53,000 times around this loop for my stack to be exceeded. I bet your servers probably are some cheap EC2 instances or something and they probably don't get nearly as deep with the stack. [snorts] Now, the crazy part about this is that the user doesn't even need to be authenticated. They just simply need access to this payload and you need to be on an old enough version of React. And so therefore, they can just send you this message and boom your computer that one single message one message means your server up in the clouds completely off. It's going to crash the process but before it crashes the process it's going to take hundreds of milliseconds if not longer to process through everything first. You see back in my day react used to just be a view library. In fact way way back in the day it used to say hey we're the V in model view controller MVC. Now I know those days are long they're those are the bygone days of yore at this point. Effectively react / next JS just does everything. I I just have a question okay? Honestly I don't really understand the entire appeal of server side components to begin with right? Your client goes over here it makes a request and all of this is to prevent yourself from having the N plus one query problem and you can also get some kind of cool page dynamic caching because the first moment you hit a suspense like component it oh my gosh look at that line that was a perfect line. It once you hit that first suspense whatever the initial HTML that comes across the wire that thing can be cached by a CDN and then all the follow up stuff is only user specific data. Like is that is that the entire reason why people use react server components? Am I crazy? This is a lot of engineering just to avoid you thinking about how to load your data. I'm just going to throw it out there. I feel like you you you could just you could just do this instead. You know you could just load the data you need. I know novel concept. All right well looks like that's it. I just kind of wanted to yap about this for a little bit cuz I thought these this was pretty interesting. There's also one with cross site scripting and how it does some you know dangerously skip HTML which is very funny by the way. It's super super funny to see react the library in which you're not supposed to have to think about HTML and being able to do or like removing any of the escaped characters or anything like that. You don't have to think about any of that. Instead, you just hand it to React and it renders it correctly and it just turns out you can't hand everything to React because some of the items underneath the hood, well, they're actually using set HTML dangerously and they weren't properly escaping things. Very, very hilarious. Anyways, so if hey, if you're using React, you better upgrade because even if you're not using Next.js, you still got that problem I just showed you right there. That's pretty serious, huh? Can I tell you Can I tell you like a little story that I'm a little ashamed of? In 2016 when Netflix was flirting with with React and putting it on a television, I was a part of the initial performance side of things and when comparing a very skinny app that has virtually no features to an app that's completely filled with features and has a decade of legacy code, you may This may surprise you, but the the skinny one was faster. And so people kept pushing it and I'm not going to lie to you guys. During my dark days right before I became jaded, but I thought React was really great in 2016 and then I used it a whole bunch and then I saw what happened and then I I stopped liking React after that. [laughter] I can't help it. I stopped liking it. But you know what happened? I learned a lot during those days, okay? I learned very, very, very valuable lessons, which was just say no early on. Just say no. No. A gen.

Get daily recaps from
The PrimeTime

AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.