Newsletter Issue #3
December 12, 2025 • 5 min read

React2Shell and AI Monoculture

By Chris Hartwig

red and black heart illustration

A recent vulnerability, CVE-2025-55182 aka React2Shell, hit React Server Components, and by extension Next.js. It’s a critical issue allowing an attacker to craft a request that leads to remote code execution on the server. If you run Next.js with the app router, you have to patch immediately or accept consequences. If your app is using the pages router instead, it means your stack is obsolete and you should still be concerned, patch Next.js and migrate to the app router (good luck!).

The interesting part is why so many people were exposed at once.

Stack hegemony

AI coding tools don’t pick frameworks because they’re appropriate. They pick frameworks because they’re statistically dominant.

Right now, that means React, tailwindcss and Next.js because the model has seen them everywhere: tutorials, GitHub repos, examples, stack overflow questions ie. all over their training data.

That’s how you end up with millions of small web apps all using the same framework, all vulnerable.

AI’s versioning trap

There’s a second, quieter problem: vibe coding freezes your dependencies in time. Most AI-generated Next.js projects are not created with the latest version. They’re bootstrapped using whatever version was dominant in the model’s training data. And once generated, nobody updates them: there’s no npm update step in vibe coding, no long-term software engineering maintenance loop.

When a vulnerability like CVE-2025-55182 hits, the fix is rarely “bump a patch version” anymore.

For your vibe coded Next.js project, it can mean:

  • jumping one or two major versions
  • rewriting data-fetching logic
  • changing middleware, upgrading react and tailwindcss (with their own breaking changes!)
  • touching a lot of code you never wanted to understand in the first place

So what should be a security patch turns into a partial rewrite. And it’s so unlikely to happen smoothly that most cloud providers had to implement a workaround at the application network layer to protect their customers.

That’s how vulnerable apps stay vulnerable.

The result of monoculture

I’ve argued against Next.js for years for purely engineering reasons: complexity, hidden behavior, large blast radius, and a tendency to couple concerns that should stay separate. But honestly, with CVE-2025-55182, I don’t even need to argue anymore.

We’ve seen this movie before: IIS, WordPress, Log4j. The problem is never “the tool is bad”, the problem is too many people made the same choice without thinking. Actually in the case of vibe coding, nobody was thinking when the stack was chosen!

An AI will happily pick your framework, scaffold your app, wire your server and client together and deploy it, but it won’t track CVEs, assess exploitability, coordinate emergency upgrades, or explain why this stack was chosen in the first place.

Vibe coding massively scales creation, but it does not scale responsibility.

Diversity as a safety property

You want diversity in stacks for the same reason we diversify cryptography, suppliers, and infrastructure: to avoid systemic failure. AI naturally pushes toward sameness, and that’s one more reason why human engineering judgment must be a counterbalance.

If AI can decide your architecture in one prompt, then nobody thought about your architecture.

And CVE-2025-55182 is what that looks like in production: millions of attempts per hour to exploit the vulnerability, on Cloudflare alone.

References

Photo by Martin Sanchez on Unsplash