HomeGuidesNext.js middleware auth bypass CVE-2025-29927
Guide
Next.js middleware auth bypass CVE-2025-29927
CVE-2025-29927 let one header skip Next.js middleware auth checks. Affected versions, the patched releases, who is safe, and how to fix your app.
Independent notes from VibeLocked. Not a pentest, and not affiliated with the tools named below.
If your Next.js app checks login in middleware.ts and you host it yourself, an old bug could let anyone skip that check. It is tracked as CVE-2025-29927. Many AI generated Next.js projects from Cursor, v0, Bolt, or Lovable put auth in middleware, so it is worth five minutes to confirm you are on a fixed version.
Checked against the Next.js postmortem, the GitHub advisory, NVD, and the Next.js docs linked below on October 14, 2026.
The short answer
| Your Next.js line | Affected versions | Fixed in |
|---|---|---|
| 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 later | No patch, upgrade or block the header |
| 16.x | Not in the affected range | Already includes the fix |
These ranges come from the GitHub advisory GHSA-f82v-jwr5-mffw and the NVD entry for CVE-2025-29927. The advisory rates it Critical, 9.1 out of 10.
| Where your app runs | Affected? |
|---|---|
| Vercel | No, protected automatically |
| Netlify | No, never affected |
| Cloudflare Workers | No, never affected |
Static export (output: 'export') |
No, there is no middleware |
Self-hosted with next start or output: 'standalone' |
Yes, if your version is in the range above |
What happened, in plain words
Middleware (Next.js 16 renamed it Proxy) runs before your pages and API routes. A common pattern is to read the session cookie there and redirect anyone who is not signed in.
Next.js used an internal header called x-middleware-subrequest to know that middleware had already run, so it would not loop forever. The problem was that Next.js also trusted that header when it came from outside. A request that included it could make Next.js skip your middleware entirely. If your only auth check lived in middleware, the protected page or route was served anyway.
The official postmortem, published by the Next.js team, explains the fix: Next.js now validates that header and filters it out if the validation fails. Patches shipped on March 17 and 18, 2025 for 14.x and 15.x, with backports to 13.5.9 and 12.3.5 a few days later.
Are you affected? Three questions
- Do you host it yourself? If your app is on Vercel, Netlify, or Cloudflare Workers, or you use a static export, you were not exposed through this bug. The postmortem confirmed that self-hosted apps using
next startoroutput: 'standalone'were affected. That includes a VPS, a Docker container, or any host that runs your app as a plain Node server. - Are you on an affected version? See the next section.
- Does your middleware do auth? If your
middleware.ts(orproxy.ts) redirects signed out users, checks roles, or guards/adminor/dashboard, that check could be skipped. If you have no middleware file, this bug had nothing to skip, but you should still upgrade.
How to check your Next.js version
Open package.json and find the next line under dependencies. A value like "^14.2.3" is a range, not the exact version you have installed. To see the real installed version, run this in your project folder:
npm ls next
The output shows something like [email protected]. Compare that number with the table above. If you use pnpm or yarn, pnpm list next or yarn why next gives the same answer. Also check the version your host actually builds with. If your lockfile is committed, that is usually the same number. For an outside view, the free Live App Scanner fingerprints the Next.js build a deployed app exposes and flags this CVE when it can see an affected version, but npm ls next is the reliable answer.
The fix: upgrade Next.js
Move to at least the fixed release for your major version, for example:
npm install [email protected]
Use 15.2.3, 13.5.9, or 12.3.5 instead if you are on those lines. Going to the newest release of your line is even better, because later releases fixed other issues too. The Next.js support policy lists which major versions still get security patches. Commit the updated package.json and lockfile, redeploy, and run npm ls next again to confirm.
If your AI tool generated the project months ago, ask it to do the upgrade and then run your app locally to confirm sign in, sign out, and protected pages still behave. Read the diff for anything else it installs on the way: a package name a model invents can be registered by an attacker (AI hallucinated packages).
If you cannot upgrade yet: block the header
The advisory says that if patching is not possible, stop outside requests that contain the x-middleware-subrequest header from reaching your Next.js app. You do that in whatever sits in front of it:
- nginx as a reverse proxy. In the
locationblock that passes traffic to Next.js, addproxy_set_header x-middleware-subrequest "";. nginx's proxy module docs say a header set to an empty string is not passed to the app. - A CDN or firewall in front of your server. Add a rule that blocks or strips requests carrying that header.
This is a stopgap for Next.js 11 or a frozen legacy app. It is not a reason to skip the upgrade.
The bigger lesson: middleware is not your auth boundary
The postmortem says plainly that the Next.js team does not recommend middleware as the only way to protect routes. The current Next.js authentication guide calls Proxy an optional place for "optimistic checks" that only read the session cookie, and says it "should not be your only line of defense in protecting your data." It recommends doing most checks "as close as possible to your data source."
So keep your middleware redirect for a smooth user experience, and also check auth where the data is:
- Route Handlers. The same guide says to treat them like public API endpoints and verify the user inside each one.
- Server Actions. Anyone can call them with a direct POST. See Next.js Server Actions security.
- Your data access code. Put a
verifySession()style helper in one module and call it before every read or write of private data. - Admin pages. A client component that redirects non-admins is UI only. Check the role in the Server Component, the action, and the handler. The client-side auth guide has a
requireAdmin()helper for Supabase and Clerk.
// app/api/orders/route.ts
import { verifySession } from '@/app/lib/dal';
export async function GET() {
const session = await verifySession();
if (!session) {
return new Response(null, { status: 401 });
}
// Only fetch orders that belong to session.userId
}
verifySession is a placeholder for your own auth helper, like the one in the Next.js guide. Filtering by the session user is the IDOR fix; fix IDOR in Next.js and Supabase has the full pattern and a two-account test. On Supabase, RLS is the backstop for a check you miss, and testing RLS policies in CI keeps it from quietly regressing. The Proxy docs add another reason: a matcher change can silently stop Proxy from running on a route, so they say to verify auth inside each Server Function rather than relying on Proxy alone.
The common vibe coded app vulnerabilities guide covers this and other missing auth patterns AI tools tend to produce.
Ask your AI tool to audit it
Open your project in Cursor or your AI tool and ask: "List every page, Route Handler, and Server Action that reads or changes private data. For each one, show where it checks the session. Flag any that are only protected by middleware.ts or proxy.ts." The security review prompt gives a fuller version.
Checklist
-
npm ls nextshows 15.2.3, 14.2.25, 13.5.9, 12.3.5, or newer in your line - Or your app runs on Vercel, Netlify, Cloudflare Workers, or is a static export
- If stuck on an old version, the proxy in front strips
x-middleware-subrequest - Every Route Handler with private data checks the session itself
- Every Server Action checks the session and ownership itself
- Middleware or Proxy is only used for redirects, not as the only lock
Sources
Questions
Is my Next.js app on Vercel affected by CVE-2025-29927?
No. The GitHub advisory says Next.js deployments hosted on Vercel are automatically protected. The Next.js postmortem also says Netlify and Cloudflare Workers were never affected, and static exports are not affected because they have no middleware. Self-hosted apps using next start or output: 'standalone' were affected.
Which Next.js version fixes CVE-2025-29927?
15.2.3 for Next.js 15, 14.2.25 for Next.js 14, 13.5.9 for Next.js 13, and 12.3.5 for Next.js 12. There is no patch for Next.js 11, so upgrade or block the x-middleware-subrequest header in front of your app. Next.js 16 is not in the affected range.
If I block the x-middleware-subrequest header, do I still need to upgrade?
Yes. The advisory lists blocking the header as a workaround for when patching is not possible. Upgrading is the real fix, and you should also move real auth checks into Route Handlers, Server Actions, and your data access code so one skipped middleware check cannot expose data.