
Next.js Middleware Auth Bypass
Contournement du mécanisme d'authentification du middleware Next.js en falsifiant l'en-tête de requête x-middleware-subrequest, permettant un accès non autorisé aux routes protégées.
Le code source du projet est extrait de P神, la version Next.js est 15.2.2 (For Next.js 15.x, this issue is fixed in 15.2.3).
Assurez-vous que Node et npm sont installés. Vérifiez les versions avec les commandes suivantes :
node -v
npm -v
Installez les dépendances et démarrez le projet
# 1. Entrez dans le répertoire du projet
cd vulenv
# 2. Installez Yarn globalement (si ce n'est pas déjà fait)
npm install -g yarn
# 3. Installez les dépendances du projet
yarn install
# 4. Démarrez le serveur de développement
npm run dev
Ou en une seule commande :
cd vulenv && npm install -g yarn && yarn install && npm run dev
Succès comme ci-dessous :


Configuration du débogage VSCode comme suit
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev",
"serverReadyAction": {
"pattern": "- Local:.+(https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
const run = withTaggedErrors(async function runWithTaggedErrors(params) {
var _params_request_body;
const runtime = await getRuntimeContext(params);
const subreq = params.request.headers[`x-middleware-subrequest`];
const subrequests = typeof subreq === 'string' ? subreq.split(':') : [];
const MAX_RECURSION_DEPTH = 5;
const depth = subrequests.reduce((acc, curr)=>curr === params.name ? acc + 1 : acc, 0);
if (depth >= MAX_RECURSION_DEPTH) {
return {
waitUntil: Promise.resolve(),
response: new runtime.context.Response(null, {
headers: {
'x-middleware-next': '1'
}
})
};
}
......
Une fonction middleware vise à détecter la profondeur des appels récursifs pour éviter les boucles infinies. Son mécanisme repose sur l'en-tête de requête x-middleware-subrequest, le divisant en plusieurs noms de sous-requêtes avec le séparateur :, et compte le nombre d'occurrences identiques au nom du middleware actuel params.name (c'est-à-dire le niveau de récursion). Lorsque le niveau de récursion atteint ou dépasse le seuil défini (par défaut MAX_RECURSION_DEPTH = 5), le middleware saute la logique principale, comme la vérification d'identité, et continue le traitement de la requête.
Astuce : éviter les appels récursifs infinis, l'idée générale est la suivante
L'utilisateur accède à /dashboard
↓
le middleware intercepte, demande /api/auth
↓
/api/auth déclenche à nouveau le middleware
↓
le middleware demande à nouveau /api/auth
↓
...
Boucle infinie ! 🌀
Le middleware s'appelle middleware, vous pouvez construire l'en-tête de requête suivant :
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
La construction ci-dessus fera en sorte que depth = 5, déclenchant directement :
if (depth >= MAX_RECURSION_DEPTH)
Si l'application place la logique de vérification d'identité dans le middleware, cela amènera le middleware à quitter la logique d'authentification et à retourner
x-middleware-next: 1
permettant à la requête de continuer vers le backend, obtenant des ressources protégées sans authentification.
Placez un point d'arrêt à l'endroit ci-dessous (chemin détaillé : CVE-2025-29927/vulenv/node_modules/next/dist/server/web/sandbox/sandbox.js) puis démarrez le débogage.

Envoyez le payload

Arrêt à l'endroit ci-dessous, vous pouvez voir que la valeur de depth est 5

Continuez l'exécution pour obtenir les ressources protégées

Écrit sur la base de Pocsuite3, voir les détails dans Poc_CVE-2025-29927.py.

Next.js and the corrupt middleware: the authorizing artifact