Next.js et la faille des middlewares corrompus

Contexte

En mars 2025, les chercheurs en sécurité Rachid.A (alias zhero) et Yasser Allam (alias inzo_) ont publié un article de recherche intitulé Next.js and the corrupt middleware: the authorizing artifact.

Cet article révèle une faille de sécurité critique affectant toutes les versions de Next.js à partir de la 11.1.4 jusqu’aux versions stables les plus récentes au moment de la publication.

La faille est enregistrée sous l’identifiant CVE-2025-29927 et a reçu un score de 9.1/10 selon le barème CVSS — un niveau considéré comme critique.

Détails de la faille

Next.js intègre un système de middleware permettant d’intercepter les requêtes HTTP avant qu’elles n’atteignent les routes de l’application.

Ces middlewares sont utilisés pour des tâches comme :

  • La réécriture de chemins d’accès
  • Les redirections côté serveur
  • L’ajout de headers HTTP (exemple CSP)
  • Et surtout, la protection des routes privées par authentification ou autorisation

C’est justement cette dernière utilisation — probablement la plus sensible — qui est totalement compromise par la faille découverte.

Compréhension technique

La faille repose sur un usage détourné d’un en-tête HTTP interne nommé x-middleware-subrequest.

Cet en-tête est utilisé par Next.js pour déterminer si une requête est une sous-requête (par exemple initiée en interne) afin d’éviter que le middleware ne soit exécuté plusieurs fois sur une même chaîne de traitements.

Mais il n’y a aucune restriction sur l’utilisation de cet en-tête.

Un utilisateur externe peut librement l’ajouter à sa requête !

Et en le forgeant correctement, il peut faire croire à Next.js que la requête a déjà été traitée par le middleware et qu’il faut la laisser passer.

Le middleware est alors complètement ignoré, même s’il devait effectuer une redirection ou refuser l’accès.

Exemples d'exploitation

Prenons une route sensible comme /admin/panel protégée par un middleware qui vérifie les cookies de session

En utilisant une requête contenant l’en-tête suivant : x-middleware-subrequest: pages/_middleware ou x-middleware-subrequest: middleware

Selon la version de Next.js en place, la requête est traitée sans que le middleware ne soit exécuté.

Résultat : accès libre à des routes qui devraient être strictement protégées !

Dans les versions les plus récentes, un autre mécanisme est en place basé sur une limite de récursivité.

Le code vérifie que le nombre d’occurrences d’un middleware donné dans la chaîne n’excède pas MAX_RECURSION_DEPTH, fixé à 5.

Il suffit donc de répéter le nom du middleware cinq fois dans le header pour déclencher le bypass.

Exemple :

x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware ou x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware

🔥 Impacts réels

Le bypass du middleware permet entre autres :

  • D’accéder sans autorisation à des pages privées
  • De court-circuiter les protections CSP, ouvrant la voie à des attaques XSS
  • D’empoisonner le cache (Cache Poisoning DoS), en forçant un CDN à stocker une mauvaise réponse (404 ou 500), rendant des pages indisponibles à grande échelle

Conditions de vulnérabilité

Le seul prérequis est que des middlewares soient utilisés, en particulier pour des tâches sensibles comme l’auth ou la réécriture conditionnelle !

Si ce n’est pas le cas, le risque est bien moindre, même s’il reste un angle possible via le cache.

🛠 Correctifs et solutions

Les mainteneurs de Next.js (Vercel) ont publié un patch le 18 mars 2025 dans la version 15.2.3, avec rétroportage vers 14.2.25

Les versions 11 à 13 ne sont plus maintenues, mais un workaround est proposé :

Filtrer ou supprimer l’en-tête x-middleware-subrequest pour toutes les requêtes HTTP entrantes

Ceci peut être fait au niveau du proxy inverse (nginx, cloudflare, vercel config etc).

🔗 Ressources