Next.js middleware is how a lot of SaaS teams ship auth. One middleware.ts file at the root of the project, one matcher config, and every protected route redirects to the login page if the session cookie is missing. It's clean. It's one of the selling points of the framework.
CVE-2026-29155 is that one file being bypassable with a single HTTP header. The bug lives in how Next.js identifies internal subrequests: when one middleware invokes another, it sets x-middleware-subrequest to track recursion depth and avoid infinite loops. The check is string-based. Send your own x-middleware-subrequest header with enough repetitions, and the framework concludes the recursion limit has been hit, returns "pass through," and serves the protected route without running your auth middleware.
Vercel patched their hosting platform at the edge within hours. Self-hosted Next.js deployments -- which is a lot of them, especially on Docker / Fly / Railway / AWS -- did not get that patch automatically. As of mid-April 2026 CISA has added this CVE to the KEV catalog because of confirmed in-the-wild exploitation against self-hosted dashboards.
What it lets an attacker do
Any route you guarded with middleware is now unauthenticated. Admin panels. User-specific pages. API handlers behind if (!session) redirect('/login') patterns. If you use middleware for auth, this is equivalent to an unauthenticated admin login for anyone who knows the URL.
The blast radius is whatever your middleware was protecting. On the small side, that's a marketing dashboard. On the large side, it's the admin surface of a multi-tenant SaaS.
How to tell if you're exposed
Two checks, both take under a minute. First, the version:
npm ls next
# or
cat package.json | grep '"next":'
If you see Next.js 14.0.x through 14.2.24, or 15.0.x through 15.1.6, and you're self-hosting, you're vulnerable. Patched versions are 14.2.25 and 15.1.7.
Second, confirm the bypass directly against a known-protected route:
curl -i https://yourapp.com/admin \
-H 'x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware'
If that returns a 200 with the admin HTML instead of a 302 to /login, you are exploitable right now. Do this test against your own staging first -- the header is harmless but an unauthenticated admin HTML response in your logs will make everyone nervous.
What the PoC looks like
The public PoC is a single header. That is the whole exploit. The header value is the string middleware repeated five times, colon-separated. Next.js counts the colons, decides it has reached the subrequest recursion limit, and bypasses the middleware chain.
We're deliberately not linking a weaponized scanner. The detection here is the curl one-liner above. If you want more, the Vercel security advisory feed contains the technical writeup, and ProjectDiscovery's writeup documents the internal logic.
Our scanner test for this
CELVEX Group runs ZERODAY-2026-0002 -- Next.js middleware auth bypass as a fully automated wave-3 check. The wave-1 probe extracts the Next.js version from the main-app bundle and the x-powered-by header; if the version falls inside the vulnerable range, wave 3 sends the single-header test against a known-protected route provided during scan scoping and verifies the response bypasses auth. Critical-severity finding when it triggers.
Module: core/test_catalog/_supplement_zeroday_2026-04-18.py, test_id ZERODAY-2026-0002.
What to do today
- Upgrade Next.js. To 14.2.25 or 15.1.7 (or newer). The upgrade is a one-line package bump and a rebuild. Run your E2E test suite on staging first -- in our sample of ten self-hosted production apps, eight upgraded cleanly and two had incidental breaking changes unrelated to this CVE.
- If you cannot upgrade today, strip the header at your reverse proxy. In nginx:
proxy_set_header X-Middleware-Subrequest "";inside every location block that proxies to Next.js. On Cloudflare, add a Transform Rule that removes the header. On ALB/CloudFront, use a request function to do the same. This is a compensating control, not a fix. - Audit your access logs. Search for any request carrying an
x-middleware-subrequestheader in the last 60 days. Legitimate traffic does not send this header from outside the Next.js runtime. Any hit is a probe or an exploitation attempt.
Sources
Check your exposure in five minutes
Run the same passive scan we used in this research against your own domain. Free, no signup required.
Scan Your Domain Free