June 23, 2026
From SSR to RSC: How Next.js Expanded Its Attack Surface
When Next.js introduced the App Router, the focus was on developer experience, performance, and modern rendering patterns. Less attention…

By Patrik Duch
1 min read
When Next.js introduced the App Router, the focus was on developer experience, performance, and modern rendering patterns. Less attention was paid to the security implications of adding React Server Components, Flight protocol, Server Actions, and several new caching layers. Collectively, these features expanded the attack surface far beyond what existed in the traditional Pages Router architecture.
The Pages Router Era
The Pages Router is still my personal preference. While the App Router was introduced as a major leap forward for developer experience, the industry has become obsessed with DX as the ultimate metric of success. Somewhere along the way, we stopped valuing system transparency, predictability, and architectural simplicity.
// pages/dashboard.tsx
export default function DashboardPage({ data }) {
return <Dashboard data={data} />;
}
export async function getServerSideProps() {
const data = await fetchDashboardData();
return {
props: {
data,
},
};
}// pages/dashboard.tsx
export default function DashboardPage({ data }) {
return <Dashboard data={data} />;
}
export async function getServerSideProps() {
const data = await fetchDashboardData();
return {
props: {
data,
},
};
}The Pages Router wasn't secure by default — but its attack surface was far more predictable.
The App Router Era
The moment you move to React Server Components, you're no longer dealing with plain HTML and JSON. Instead, you're interacting with a custom serialization format known as the React Flight protocol.
And adding declarations such as "use client" and "use server" is not something that I would call a great Developer Experience (DX).
The industry calls that progress. The industry calls that a better developer experience.
I call it unnecessary complexity.
But that Flight protocol — the one you didn't ask for and can't see — was a new deserialization attack surface. And in December 2025, that surface turned into CVE-2025–55182: an unauthenticated remote code execution.
https://vercel.com/changelog/cve-2025-55182
By the time I finished reading the advisory, I had already moved my app from the App Router back to the Pages Router. 😄