Rustine

CVE-2025-29927: The Next.js Middleware Bypass

A web request (horizontal arrow) walks around a checkpoint gate standing for the Next.js middleware.

A web request bypassing a checkpoint gate that stands for Next.js middleware.
Contents
  1. What applies to you
  2. Why this is serious for you
  3. The mechanism, in plain terms
  4. The prompt to paste into your agent
  5. Don't put all your security in the middleware
  6. Frequently asked questions
  7. Am I affected if I don't use middleware for authentication?
  8. I'm on Vercel, do I need to do anything?
  9. I'm on Next.js 11, what should I do?
  10. How do I check whether my app was already hit?
  11. Is middleware enough to protect my routes?
  12. Sources
Does it affect you
Vulnerability
CVE-2025-29927 · NVD entry
Is your version affected? Rustine reads it on your site in a minute.Scan my site

CVE-2025-29927 is a critical flaw (CVSS 9.1) in the Next.js framework. It lets anyone bypass the authorization checks you put in middleware, simply by adding an HTTP header named x-middleware-subrequest to the request. Every recent line is affected before the patches published on 21 March 2025: 12.3.5, 13.5.9, 14.2.25 and 15.2.3. What to do now: upgrade Next.js, or block that header if an upgrade isn't possible right away.

What applies to you

  • Severity: critical, CVSS 9.1. Exploitable remotely, without authentication, without user interaction.
  • Weakness: CWE-863 (incorrect authorization).
  • Publication: the CVE has been public since 21 March 2025.
  • Exploitation likelihood: EPSS score of 99.2% (99.9th percentile).
  • Hosting: apps on Vercel are automatically protected (routing there is decoupled). Netlify and Cloudflare Workers were never affected. Self-hosted setups (next start, output: 'standalone') are affected.
Line Affected versions Fixed version
15.x 15.0.0 to 15.2.2 15.2.3
14.x 14.0.0 to 14.2.24 14.2.25
13.x 13.0.0 to 13.5.8 13.5.9
12.x 12.0.0 to 12.3.4 12.3.5
11.x 11.1.4 and up none — out of support

Next.js 11.x never got a patch: the line is out of support. The workaround applies (see below).

Why this is serious for you

Middleware is where a lot of AI-generated apps put their access control: checking a cookie, redirecting to the login page, blocking admin routes. It's convenient, because that code runs before rendering. If you built your app with Lovable or another AI tool, there's a good chance your auth check lives exactly there. An app that gets bypassed at that point opens its admin pages, its dashboards and its API routes all at once.

It's the same family of risk as an authorization checked in the wrong place: the check runs somewhere the attacker can skip, and a stranger ends up reading what was never meant for them.

The mechanism, in plain terms

Next.js runs middleware before routing and caching. The catch: middleware runs in a different process from the one that renders the page. To avoid calling itself in an infinite loop of sub-requests, Next.js uses an internal header, x-middleware-subrequest. When the middleware makes an internal request back to the app, that header tells the router: "middleware already ran, skip it."

The flaw comes down to one detail: that header was accepted without validation. Anyone could send it from the outside. The router saw it, believed it was a legitimate internal sub-request, and skipped the middleware. Result: the authorization check never ran, while the page or route was still served.

Two panels: a request that goes through middleware, then a request that bypasses it.

The fix adds validation on that header: if it doesn't come from a real internal sub-request, it gets filtered before reaching the router.

The prompt to paste into your agent

text
Fix CVE-2025-29927 (Next.js middleware bypass) in this project.

1. Upgrade Next.js to a fixed version for the project's line (check the "next" dependency in package.json):
   - 15.x -> npm install next@15.2.3
   - 14.x -> npm install next@14.2.25
   - 13.x -> npm install next@13.5.9
   - 12.x -> npm install next@12.3.5

2. If the project is on Next.js 11.x (no patch available), add a rule at the reverse proxy, WAF or entry middleware layer that strips the x-middleware-subrequest header from every incoming request before it reaches the Next.js server.

3. Then verify that:
   - "npm ls next" returns a fixed version (>= 15.2.3, >= 14.2.25, >= 13.5.9 or >= 12.3.5);
   - routes protected by middleware still refuse access without a valid session;
   - no security scan reports CVE-2025-29927 anymore.

If you're on Vercel, the platform already protects you. Upgrade anyway: the day you deploy elsewhere or self-host, you take the risk back.

Don't put all your security in the middleware

This flaw is a reminder of a simple rule: middleware is a first door, not the only one. A solid app checks authorization at several levels.

  • In middleware, to redirect signed-out visitors early.
  • Server-side, in the route handler, where the data is actually read.
  • As close to the data as possible, with row level security on Supabase.

If one layer falls, the others hold.

A request passes through three successive control layers, illustrating defense in depth.

Frequently asked questions

Am I affected if I don't use middleware for authentication?

The flaw only triggers if an authorization check happens in middleware. If your middleware only rewrites URLs or redirects non-sensitive cases, the risk is limited. Upgrade anyway: you can add a check in middleware tomorrow without thinking about it again.

I'm on Vercel, do I need to do anything?

Vercel automatically protects apps hosted there, because its routing is decoupled from Next.js. Netlify and Cloudflare Workers were never affected. You should still upgrade for deployments outside the platform, and to stay clean if you change hosting.

I'm on Next.js 11, what should I do?

Next.js 11 is out of support and never got a patch. Two options: block the x-middleware-subrequest header upstream (reverse proxy or WAF), or migrate to a supported line. Migration is the durable fix.

How do I check whether my app was already hit?

Look through your access logs for requests carrying the x-middleware-subrequest header. Also check that your protected routes (admin, dashboard, API) haven't received access without a session. That's a check to run on your own site, without sending anything at someone else's.

Is middleware enough to protect my routes?

No. Use it to redirect early, but check authorization as close to the data as possible: in the route, and with row level security on Supabase. That's the only way to hold when middleware is bypassed.

Sources

Before you deploy, scan your app the way a stranger would. It shows what leaks with the proof (the request and what it returns), and gives you the fix to paste into your coding agent.

Is your app affected? Find out in a minute.Scan my site