The most serious Next.js security vulnerability disclosed to date is CVE-2025-29927, a middleware authorization bypass that lets an attacker skip every check your middleware performs by sending one crafted HTTP header. If your app puts authentication, redirects, or path rewriting in middleware.ts and you never validate the origin of internal headers, an unauthenticated request can reach routes you thought were protected. The flaw was disclosed in March 2025 and is straightforward to exploit, which is exactly why it deserves careful attention rather than a quick version bump and a shrug.
What is CVE-2025-29927?
Next.js middleware runs before a request reaches your route handlers, and it is the natural place teams put gatekeeping logic: "is this user logged in, if not redirect to /login." Internally, Next.js uses a header called x-middleware-subrequest to prevent middleware from recursively invoking itself. The framework trusted that header without checking where it came from. An attacker who sets x-middleware-subrequest to the right value convinces Next.js that middleware has already run, so the framework skips it entirely and passes the request straight through to the underlying route.
The practical result: any protection you implemented purely in middleware evaporates. Admin dashboards, authenticated API routes, and gated content become reachable by anyone who knows the header trick. The vulnerability carries a critical severity rating because it needs no authentication, no user interaction, and no special positioning on the network.
Which versions are affected?
This is where teams need to be precise, because the patched release differs per major version line. According to the official advisory, the fixed versions are:
- Next.js 15.x: upgrade to
15.2.3or later (versions15.0.0through15.2.2are vulnerable) - Next.js 14.x: upgrade to
14.2.25or later (versions14.0.0through14.2.24are vulnerable) - Next.js 13.x: upgrade to
13.5.9or later - Next.js 12.x: upgrade to
12.3.5or later
Earlier releases in the 11.1.4 through 13.5.6 range are also affected. If you are on any version below your line's patched release and you rely on middleware for authorization, treat this as an emergency patch, not a routine dependency update.
One important nuance: the exposure depends on how Next.js is deployed. Applications hosted on Vercel and some managed platforms received edge mitigations that strip the dangerous header before it reaches your app. Self-hosted deployments — next start behind your own reverse proxy, Docker containers, custom Node servers — are the ones most exposed, because nothing upstream is filtering the header for you.
How the exploit works
Middleware in Next.js typically looks like this:
// middleware.ts
import { NextResponse } from "next/server";
export function middleware(request) {
const session = request.cookies.get("session");
if (!session) {
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
export const config = { matcher: ["/dashboard/:path*"] };
The intent is clear: no session, no dashboard. The bug is that Next.js decides whether to run this function at all based on the untrusted x-middleware-subrequest header. When the header signals that a subrequest is already in flight, the runtime short-circuits and never evaluates your session check. A request to /dashboard carrying the header reaches the route as though the middleware waved it through.
I am deliberately not publishing the exact header payload here, because the point is remediation, not handing anyone a ready-made request. The value follows a predictable pattern tied to the framework internals, and public write-ups documented it within days of disclosure — which is the whole reason patching quickly matters.
How to fix and mitigate it
The primary fix is the version upgrade. Bump Next.js to the patched release for your major line and redeploy. That closes the header-trust bug at the source.
If you cannot upgrade immediately — a common reality when a major version jump pulls in breaking changes — block the header at your edge. Configure your reverse proxy, CDN, or WAF to strip any incoming x-middleware-subrequest header from client requests before they reach the app. Clients never have a legitimate reason to send it. An Nginx snippet:
proxy_set_header x-middleware-subrequest "";
The deeper lesson outlives this one CVE: middleware should not be your only line of defense. Authorization belongs as close to the data as possible. Check the session again inside the route handler or the server action that actually returns sensitive data, so a bypass of the outer layer still hits an inner one. Defense in depth means a single trusted-header bug does not become a full account-takeover path.
Beyond this CVE: the broader Next.js risk surface
CVE-2025-29927 is the headline, but Next.js apps accumulate risk in familiar places. Server actions that trust client-supplied IDs without an ownership check leak other users' data. Environment variables prefixed with NEXT_PUBLIC_ are bundled into client JavaScript, so a stray secret in one of them ships to every browser. Image optimization endpoints have historically been abused as open proxies when remotePatterns is too permissive. And the dependency graph underneath a typical Next.js project is enormous, which is where transitive vulnerabilities hide.
That last point is worth dwelling on. The Next.js package itself is one line in your package.json, but it pulls in React, the compiler toolchain, and dozens of transitive packages. A vulnerability three levels down in the tree affects you just as much as one in Next.js itself, and no version bump of Next.js will fix it. Continuous dependency scanning — the kind of software composition analysis you can read more about in our SCA product overview — is what surfaces those transitive issues before they reach production. An SCA tool such as Safeguard can flag a vulnerable transitive dependency and tell you whether your code actually reaches the affected function, which is the difference between a real fix and version-bump busywork.
For runtime issues that only appear when the app is exercised — the header bypass being a perfect example — dynamic testing catches what static scanning misses. Pairing dependency analysis with dynamic application security testing gives you both the "what's in my tree" and the "what actually breaks when hit" views.
FAQ
Is CVE-2025-29927 exploitable if I do not use middleware?
If your app has no middleware.ts performing authorization, the header trick has nothing to bypass, so the practical impact is low. But you should still patch, because the header-trust behavior is a framework-level flaw and you may add middleware later. Treat the upgrade as mandatory regardless.
Are Vercel-hosted apps safe?
Vercel deployed edge mitigations that strip the header before it reaches your application, which significantly reduces exposure for apps hosted there. Self-hosted deployments are the primary concern. Even on a managed platform, upgrade the package so your protection does not depend on the hosting layer alone.
Can a WAF fully protect me without upgrading?
Stripping the x-middleware-subrequest header at the edge is an effective stopgap and blocks the known exploit path. It is not a substitute for the patch, because a WAF rule can be misconfigured or bypassed, and the underlying trust bug remains in your code. Use header stripping to buy time, then upgrade.
How do I find other vulnerabilities in my Next.js dependencies?
Run software composition analysis against your package-lock.json or pnpm-lock.yaml on every build. That inventories every direct and transitive package, matches versions against advisory databases, and flags anything with a known CVE — including issues far below Next.js in the tree that a framework upgrade alone would never touch.