In short
- A request carrying the internal
x-middleware-subrequestheader made Next.js skip middleware. A page whose only login check sat inmiddleware.tsopened for anyone, with no account. - Affected: Next.js 11.1.4 to 12.3.4, 13.x before 13.5.9, 14.x before 14.2.25 and 15.x before 15.2.3, on a server you run with
next startor the standalone output. Vercel, Netlify, Cloudflare Workers and static exports were not exposed. - 15.2.3, 14.2.25, 13.5.9 and 12.3.5 are a floor, not a target. The middleware bypasses disclosed in 2026 are fixed only on 15.5 and 16, so upgrade to 16.4.5 or 15.5.29.
- If you cannot upgrade today, strip the header at your reverse proxy or firewall. Cloudflare's managed rule for this CVE is opt-in, so sitting behind Cloudflare does not cover you by default.
- The lasting fix is a session check in each page, route handler and Server Action, not only in middleware (called Proxy since Next.js 16).
On this page
What CVE-2025-29927 is, in plain words
Next.js middleware is a file, middleware.ts (renamed proxy.ts in Next.js 16), that runs on the server before a page is rendered. Many apps put their login check there: no session cookie, redirect to /login. The Next.js authentication guide shows exactly that pattern, as a quick first filter.
To stop middleware from calling itself in an endless loop, Next.js marked its own internal requests with a header, x-middleware-subrequest. The flaw: Next.js also trusted that header when it came from the internet. A request carrying the right value made Next.js skip middleware and render the page as if the check had passed. No account, no special tool: one HTTP header. Allam Rachid and Allam Yasser reported it on February 27, 2025, and the advisory went public on March 21, 2025.
What a stranger can do with it
| If your middleware... | Skipping it gives a stranger... |
|---|---|
Redirects signed-out visitors to /login | The protected page itself: dashboard, settings, admin screens, rendered with whatever the page loads on the server |
Lets only admins into /admin | The admin page, unless the page checks the role again |
Sets security headers such as Content-Security-Policy | The page without them, which removes a defense against cross-site scripting |
| Rewrites paths, for example by language | An error page that a cache in front of your app can store and serve to every visitor |
The limit matters as much as the risk. The bypass skips middleware and nothing else. If the page, the route handler or your data layer checks the session again, the stranger hits that second check, and database rules such as Supabase row level security still apply. It does not run code on your server either: it is an authorization bypass, not remote code execution like React2Shell.
Severity and exploitation status
The CVSS 3.1 base score is 9.1, critical, with the vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N: reachable over the network, low complexity, no privileges, no user interaction, high impact on confidentiality and integrity. The score comes from GitHub, the CVE numbering authority (CNA) that published the record. NVD has analyzed the CVE and shows that same score without publishing one of its own. The weakness is improper authorization: CWE-285 for the CNA, CWE-863 for NVD.
Who is affected
Three conditions together: a vulnerable version, a server that runs Next.js itself, and middleware that does the access control.
| Setup | Affected by CVE-2025-29927? |
|---|---|
| Next.js 11.1.4 to 12.3.4 | Yes, fixed in 12.3.5. The 11.x line got no patch of its own |
| Next.js 13.0.0 to 13.5.8 | Yes, fixed in 13.5.9 |
| Next.js 14.0.0 to 14.2.24 | Yes, fixed in 14.2.25 |
| Next.js 15.0.0 to 15.2.2 | Yes, fixed in 15.2.3 |
| Next.js 15.2.3 and later, and every 16.x | No, but later middleware bypasses may apply, see below |
Self-hosted: next start, the standalone output in Docker, a VPS | Yes, on a vulnerable version |
| Hosted on Vercel | No: Vercel's routing runs in a separate system, which made it, in Vercel's words, incidentally invulnerable |
| Netlify, Cloudflare Workers | No, per Vercel's postmortem: their routing is decoupled too |
Static export (output: 'export') | No: middleware does not run without a server |
| React without Next.js, such as a Vite single-page app | No: there is no Next.js middleware |
next start for you, treat it as self-hosted.One detail differs between sources. The CVE record and NVD start the range at 11.1.4, the last 11.x release; GitHub's npm advisory starts at 12.0.0, the release that introduced middleware, and sends 11.x users to the workaround. Either way, an app on 11.1.4 or 12.x needs 12.3.5 or later.
Apps built with AI tools
v0 generates Next.js apps and publishes them on Vercel, which was not exposed; the same code run with next start on your own server is, on a vulnerable version. A project created with create-next-app today starts on Next.js 16, so this CVE mostly concerns older projects and templates pinned to old versions. The v0 security guide covers the rest of a generated Next.js app.
Behind Cloudflare is not the same as on Cloudflare
If your server runs next start and Cloudflare only sits in front of it, requests still reach your vulnerable server. Cloudflare's managed WAF rule for this CVE is opt-in: you turn it on yourself, on the Pro plan and above. Cloudflare switched it off by default on March 22, 2025, after it made requests fail on sites that use auth middleware with third-party auth vendors. On the Free plan, Cloudflare suggests a custom rule, shown below. Akamai's rule also defaults to alert, not block.
How to check your Next.js version
Check the version that is installed, not the range in package.json: "next": "^14.1.0" can still be pinned to 14.1.0 by your lockfile. At the root of the project:
# npm
npm ls next
# pnpm (add -r in a monorepo)
pnpm why next
# yarn
yarn why next
# what the Next.js CLI reports
npx next --version# package-lock.json
grep -A1 '"node_modules/next"' package-lock.json
# pnpm-lock.yaml
grep -E '^ /?next@' pnpm-lock.yaml
# yarn.lock (Yarn 1 and Yarn Berry)
grep -A1 -E '^"?next@' yarn.locknext.Then check what production runs. Open your live site, open the browser console and type next.version. It catches the case where the repository is patched but an old container still serves the traffic.
How to check your live app
A version tells you whether the flaw is present. It does not tell you whether a page depends on middleware alone, which is what turns the flaw into a leak. Two checks answer that.
- Read each protected page as if middleware did not exist. In
app/dashboard/page.tsx, the admin pages, every route handler and every Server Action: is there a session check of its own, such asverifySession(),auth()orgetUser(), before data is loaded? If the only check is inmiddleware.ts, that page is open to this CVE on a vulnerable version, and to the 2026 bypasses on newer ones. - Search your access logs for requests carrying
x-middleware-subrequest. The default nginx log format only records the referer and user agent headers, so add$http_x_middleware_subrequestto yourlog_format. On a self-hosted app, that header arriving from the internet is a probe.
Keybrum runs this check against the live app. It finds the pages that send a signed-out visitor to sign-in, or answer 401 or 403, then requests each one again the way CVE-2025-29927 allows, and as a router prefetch. If the page comes back, the finding shows both requests side by side. It sends only GET requests, keeps a redacted excerpt as proof rather than the page, and runs only on apps whose owner proved ownership.
How to fix CVE-2025-29927
Upgrade. The first fixed versions are 15.2.3, 14.2.25, 13.5.9 and 12.3.5, released between March 17 and March 23, 2025. With the fix, Next.js validates the header against a random id it generates itself and strips it when validation fails. A low-severity follow-up, CVE-2025-30218, let that id leak to third-party hosts that middleware fetched; 15.2.4, 14.2.26, 13.5.10 and 12.3.6 close it, and Cloudflare told its customers to install those.
In November 2026, those versions are a floor. Next.js 14 and older are no longer supported, and the middleware bypasses disclosed in 2026 are fixed only on the 15.5 and 16 lines. Move to the current patch of a supported line:
# Next.js 16 (Active LTS), current patch on November 6, 2026
npm install [email protected]
# Next.js 15 (Maintenance LTS, security releases until January 31, 2027)
npm install [email protected]
# the same with pnpm or yarn
pnpm add [email protected]
yarn add [email protected]Next.js 16 renamed middleware to proxy. npx @next/codemod@canary middleware-to-proxy . renames the file and the function. The lesson of this CVE carries over: proxy is a first filter, not the lock.
If you cannot upgrade today: block the header
The advisory's workaround is to stop external requests carrying x-middleware-subrequest from reaching your Next.js server. You cannot do it in middleware, since middleware is what gets skipped. Do it in the reverse proxy or the firewall in front.
location / {
# drop the header before the request reaches Next.js
proxy_set_header x-middleware-subrequest "";
# repeat the proxy_set_header lines of your server block here
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:3000;
}example.com {
reverse_proxy 127.0.0.1:3000 {
header_up -x-middleware-subrequest
}
}On Cloudflare, create a custom WAF rule with the expression (len(http.request.headers["x-middleware-subrequest"]) > 0) and the action Block, or Log first to see what it would catch. On the Pro plan and above, you can turn on the managed rule for this CVE instead.
What to do after upgrading
- 1
Confirm production runs the fix
Redeploy, then type
next.versionin the console of your live site. On a self-hosted app, make sure the container that serves traffic was rebuilt: an old image keeps the old version running. - 2
Put the real check next to the data
Keep middleware for the redirect if you like, and add a session check in every page, route handler and Server Action that loads private data. The Next.js authentication guide says Proxy "should not be your only line of defense in protecting your data".
- 3
Look back at your logs
If your app was self-hosted on a vulnerable version, search your logs for the header, as far back as they go. If a page with personal data was reached that way, handle it as a data exposure: find out what was shown, and to whom.
- 4
Watch for the next bypass
Every new kind of request Next.js accepts, such as prefetch URLs and data routes, is one more path a middleware rule can miss. That is how the 2026 advisories below happened. Keep
nexton the current patch.
// app/dashboard/page.tsx
import { redirect } from 'next/navigation'
import { verifySession } from '@/lib/dal' // reads and verifies the session cookie
export default async function DashboardPage() {
const session = await verifySession()
if (!session) redirect('/login')
// load only this user's rows
const projects = await getProjects(session.userId)
return <Dashboard projects={projects} />
}A session check is half of it. Loading only the rows that belong to that session is the other half, or one signed-in user reads another's data: see IDOR and broken access control.
Related CVEs: the middleware bypass family
CVE-2025-29927 is the best known of a series. Each one finds a request that reaches a page without matching the middleware rule meant to guard it.
| CVE | What it does | Severity | Fixed in |
|---|---|---|---|
| CVE-2024-51479 | Authorization in middleware based on the pathname could be bypassed | High, 7.5 | 14.2.15 |
| CVE-2025-29927 | An internal header makes Next.js skip middleware | Critical, 9.1 | 15.2.3, 14.2.25, 13.5.9, 12.3.5 |
| CVE-2025-30218 | The id added by that fix could leak to third-party hosts | Low | 15.2.4, 14.2.26, 13.5.10, 12.3.6 |
| CVE-2026-44573 | Pages Router with i18n: data requests without a locale skip middleware | High, 7.5 | 15.5.16, 16.2.5 |
| CVE-2026-44574 | Crafted query parameters change the dynamic route value while the path still looks the same to middleware | High, 8.1 | 15.5.16, 16.2.5 |
| CVE-2026-44575 | App Router segment-prefetch and .rsc URLs are not matched by the middleware rule | High, 7.5 | 15.5.16, 16.2.5 |
| CVE-2026-45109 | The 44575 fix did not cover middleware.ts built with Turbopack | High, 7.5 | 15.5.18, 16.2.6 |
| CVE-2026-64642 | App Router built with Turbopack and a single locale | High, 8.3 (CVSS 4.0) | 16.2.11 |
Other Next.js CVEs work differently: CVE-2024-34351 is a server-side request forgery in Server Actions, and React2Shell runs code on the server. The Next.js security guide covers the framework as a whole, and vibe coding security risks covers what AI-built apps leak most often.
Timeline
| Date | Event |
|---|---|
| February 27, 2025 | Allam Rachid and Allam Yasser report the flaw to Vercel, first for Next.js 12.x. A second email on March 1 extends it to recent versions. |
| March 14 | Vercel's security team escalates the report, and the Next.js team confirms it. |
| March 17 and 18 | Next.js 14.2.25, then 15.2.3, ship the fix. GitHub assigns CVE-2025-29927. |
| March 21 | The advisory GHSA-f82v-jwr5-mffw and the CVE go public. |
| March 22 | Vercel says its customers are not affected. Cloudflare ships a WAF rule and makes it opt-in the same day. Next.js 13.5.9 ships as a backport. |
| March 23 | Next.js 12.3.5 ships as a backport. |
| March 24 | Akamai deploys a detection rule. Next.js 15.2.4, 14.2.26, 13.5.10 and 12.3.6 fix the follow-up, CVE-2025-30218, whose advisory follows on April 2. |
| May 11, 2026 | Three new middleware and proxy bypasses, CVE-2026-44573, CVE-2026-44574 and CVE-2026-44575, fixed in 15.5.16 and 16.2.5. |
| July 22, 2026 | CVE-2026-64642, a bypass with Turbopack and a single locale, fixed in 16.2.11. |
| November 3, 2026 | Next.js 16.4.5 and 15.5.29, the current patches on the two supported lines. |
Questions
Is my Next.js app vulnerable to CVE-2025-29927?
It is if three things are true: next is between 11.1.4 and 15.2.2 without the fix for its line (12.3.5, 13.5.9, 14.2.25 or 15.2.3), you run the server yourself with next start or the standalone output, and middleware is where your login or role check happens. Apps on Vercel, Netlify or Cloudflare Workers, and static exports, were not exposed. Check the version in your lockfile, not the range in package.json.
What is the x-middleware-subrequest header?
An internal header that Next.js added to requests made by middleware itself, so that middleware would not call itself in an endless loop. Before the fix, Next.js also accepted it from outside, and a request carrying it could skip middleware. Fixed versions validate the header and strip it when the check fails.
Is a Next.js app on Vercel affected by the middleware bypass?
No. Vercel's routing runs in a separate system, so the header could not make deployments there skip middleware, and Vercel said its customers were not affected. It still recommends upgrading, and the same code moved to your own server would be exposed.
Does Next.js 16 have this middleware bypass?
Not this one: it was fixed in 15.2.3, months before Next.js 16 came out. Next.js 16 renamed middleware to proxy, and 2026 brought new middleware and proxy bypasses through prefetch URLs, route parameters and locales, fixed in 16.2.5, 16.2.6 and 16.2.11. Run the current patch, 16.4.5 in November 2026.
How do I fix the Next.js auth bypass without upgrading?
Strip or block the x-middleware-subrequest header before requests reach Next.js: in nginx with proxy_set_header x-middleware-subrequest "";, in Caddy with header_up -x-middleware-subrequest, or with a WAF rule. It is a stopgap until you upgrade and add session checks in your pages and routes.
Was CVE-2025-29927 exploited in the wild?
It is not in CISA's Known Exploited Vulnerabilities catalog, and no primary source reports a confirmed breach through it, though Akamai and Datadog both saw probes. Press coverage of a December 2025 campaign called PCPcat lists it, but credits it with running code on servers, which this CVE cannot do on its own. FIRST's EPSS model puts the chance of exploitation in the next 30 days at 0.99, so treat an unpatched self-hosted app as exposed.
Sources
- 1.Authorization Bypass in Next.js Middleware (GHSA-f82v-jwr5-mffw), Next.js (GitHub security advisory)
- 2.CVE-2025-29927 Detail, NIST National Vulnerability Database
- 3.CVE-2025-29927 record, CVE Program
- 4.Postmortem on Next.js Middleware bypass, Vercel
- 5.Next.js and the corrupt middleware: the authorizing artifact, Allam Rachid (zhero) and Allam Yasser (inzo_)
- 6.Vercel Firewall proactively protects against vulnerability with middleware, Vercel
- 7.CVE-2025-30218, Vercel
- 8.New managed WAF rule for Next.js CVE-2025-29927, Cloudflare
- 9.Detecting and Mitigating an Authorization Bypass Vulnerability in Next.js, Akamai
- 10.Understanding CVE-2025-29927: The Next.js Middleware Authorization Bypass Vulnerability, Datadog Security Labs
- 11.Known Exploited Vulnerabilities Catalog, CISA
- 12.Next.js has a Middleware / Proxy bypass in App Router applications via segment-prefetch routes (GHSA-267c-6grr-h53f), GitHub Advisory Database
- 13.How to implement authentication in Next.js, Next.js Docs
- 14.proxy.js (Migration to Proxy), Next.js Docs
- 15.Support Policy, Next.js
- 16.November 2026 Security Release, Next.js
- 17.Exploit Prediction Scoring System (EPSS), FIRST
- 18.ngx_http_proxy_module: proxy_set_header, nginx