Full Report
NextJS is a super popular React framework with a ton of extra functionality. In fact, this website is built on top of it. The author of this post was reviewing NextJS and found a way to circumvent the middleware, which is commonly used for authentication. Within the framework, there is a check for recursive requests. For instance, if the middleware itself is making a request to the server. This is done by setting the x-middleware-request header with the path of the middleware being executed. For every piece of middleware it sees, a colon-delimited path is added. If the middleware has already been seen, then the code simply skips the middleware. As it turns out, it's possible to specify this header yourself! So, if you know the path of the middleware you want to skip then adding x-middleware-subrequest: my_path skips the check. If this is used for authentication/authorization, then it's a horrible vulnerability. The path is somewhat guessable and the header can be used as a polyglot as well. Initially, they found this in an old version of the package. Since that code had been removed, they assumed only older versions were affected. In reality, the code had been moved somewhere else. It's best to report vulnerabilities, even if they only affect older versions. You never know what you're missing about impact as a bug hunter. Instead of needing to specify the path, it's super simple: middleware or src/middleware. With the changing of the path, it actually makes it easier. Additionally, there is a now a recursive check with a maximum of 5. So, middleware: just needs to be repeated 5 times now. They used this exploit on a few bug bounty programs. One program was using the middleware as a rewrite rule. They knew this because of a header in the response. By using this vulnerability, they were able to visit the admin page. On another program, they used this as a cache poisoning DoS via forcing a 404 response by skipping the rewrite rules. Overall, an excellent write up on the discovery and exploitation of a NextJS vulnerability. I learned a ton about the framework, exploitation, and proper disclosure from this. Great work!
Analysis Summary
# Vulnerability: Next.js Middleware Authorization Bypass
## CVE Details
- **CVE ID:** CVE-2025-29927
- **CVSS Score:** Not yet finalized (Estimated High/Critical)
- **CWE:** CWE-287: Improper Authentication / CWE-639: Instance-id Injection
## Affected Systems
- **Products:** Vercel Next.js Framework
- **Versions:** All versions prior to v15.2.3, v14.2.24, and v13.5.11.
- **Configurations:** Any application utilizing Next.js Middleware for authentication, authorization, or routing rules (rewrites).
## Vulnerability Description
The vulnerability stems from how Next.js tracks recursive middleware execution. To prevent infinite loops when middleware makes internal requests, the framework uses the `x-middleware-subrequest` header. Next.js appends the middleware's "name" (path) to this header: if a incoming request already contains the current middleware's name in this colon-delimited list, the framework assumes the middleware has already executed and skips it.
Security researchers discovered that this header can be manually injected by an external attacker. By providing the expected middleware identifier in the request headers, an attacker can trick the framework into skipping the security logic entirely. While newer versions implemented a maximum recursion depth of 5, this was bypassed by simply repeating the identifier 5 times.
## Exploitation
- **Status:** PoC available; confirmed exploitation in bug bounty environments.
- **Complexity:** Low (requires knowledge of the middleware's internal name/path).
- **Attack Vector:** Network (Remote).
**Proof of Concept (PoC) Logic:**
An attacker provides a header such as:
`x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware`
Alternatively, for applications using a `src/` directory:
`x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware`
## Impact
- **Confidentiality:** High (Bypass of authorization to access restricted pages like `/admin`).
- **Integrity:** High (Ability to bypass security headers like CSP or rewrite rules).
- **Availability:** High (Can lead to Cache Poisoning DoS by forcing 404 responses or incorrect cached states).
## Remediation
### Patches
Users should upgrade to the following versions or higher:
- **Next.js 15.x:** Upgrade to **v15.2.3**
- **Next.js 14.x:** Upgrade to **v14.2.24**
- **Next.js 13.x:** Upgrade to **v13.5.11**
### Workarounds
- Implement secondary authorization checks within the actual page/API route logic (Defense in Depth).
- Configure a Web Application Firewall (WAF) or Reverse Proxy to strip the `x-middleware-subrequest` header from all incoming external user requests before they reach the Next.js server.
## Detection
- **Indicators of Compromise:** Unusual requests containing the `x-middleware-subrequest` header originating from external IP addresses.
- **Detection Methods:** Audit web server logs for any incoming traffic carrying the `x-middleware-subrequest` header, as this header is intended for internal framework use only.
## References
- **Vendor Advisory:** [https://github.com/vercel/next.js/security/advisories/GHSA-9763-798x-r9r3](https://github.com/vercel/next.js/security/advisories/GHSA-9763-798x-r9r3)
- **Researcher Write-up:** [https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware](https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware)