Context
On March 21, 2025, the Next.js team disclosed a critical vulnerability affecting the framework's middleware system. The flaw allows a remote attacker to bypass any authentication or authorization logic implemented in middleware.ts / middleware.js files by forging an internal HTTP header used by Next.js for its routing.
The vulnerability is particularly severe because many Next.js applications rely exclusively on middleware to protect their routes — with no additional authorization layer on the server side or within API routes.
It is listed on CISA's Known Exploited Vulnerabilities catalog.
Affected Versions
- Next.js 12.x < 12.3.5
- Next.js 13.x < 13.5.9
- Next.js 14.x < 14.2.25
- Next.js 15.x < 15.2.3
Exploitation Mechanism
Next.js internally uses the x-middleware-subrequest header to distinguish middleware-processed requests from internal sub-requests, avoiding infinite loops.
The flaw: this header is not filtered on incoming requests. An attacker can inject it into their HTTP request to make Next.js believe the request has already gone through internal middleware processing, causing a complete middleware bypass.
GET /admin/dashboard HTTP/1.1
Host: example.com
x-middleware-subrequest: middleware
This single header is enough to bypass any middleware.ts protecting /admin.
Impact
Any protection logic implemented in middleware can be bypassed:
- Authentication — access to routes restricted to logged-in users
- Role-based authorization — access to admin or premium sections
- JWT / session token verification — complete bypass
- Geo-restriction or IP allowlist — circumvented
- Maintenance mode redirects — site accessible during maintenance
The actual impact depends on the criticality of the protected routes: admin dashboards, private APIs, user data, etc.
Detection
Check whether your version is vulnerable:
# Check installed Next.js version
cat package.json | grep '"next"'
# or
npx next --version
Search for suspicious access in your logs:
# Nginx — requests with the x-middleware-subrequest header
grep -i "x-middleware-subrequest" /var/log/nginx/access.log
# Look for abnormal access to protected routes
# (IPs without valid sessions accessing /admin, /api/admin, etc.)
grep "/admin" /var/log/nginx/access.log | grep -v "302\|301"
Remediation
-
Update Next.js to a patched version:
- 12.x → 12.3.5
- 13.x → 13.5.9
- 14.x → 14.2.25
- 15.x → 15.2.3
npm install next@latest # or specific version npm install next@14.2.25 -
Do not rely solely on middleware for authorization — add session/token verification in each sensitive API route and Server Component:
// In an API route or Server Component import { getServerSession } from "next-auth/next"; const session = await getServerSession(authOptions); if (!session) { return new Response("Unauthorized", { status: 401 }); } -
Block the header at the reverse proxy level if an immediate update is not possible (temporary mitigation):
# Nginx — strip the header before passing to Next.js proxy_set_header x-middleware-subrequest "";# Apache RequestHeader unset x-middleware-subrequest
Recommendations
- Defense in depth — middleware is a first filter, not the only line of defense: always verify authorization close to the data
- Keep Next.js updated — subscribe to security alerts on the GitHub repository (
vercel/next.js) - Audit protected routes — identify which routes are protected exclusively by middleware and add a server-side authorization layer for the most critical ones
- Penetration test your middleware — include tests verifying that protected routes correctly return 401/403 in the absence of valid credentials