Le monde Kubernetes vient d’être secoué par la découverte d’une vulnérabilité critique surnommée IngressNightmare. Cette faille permet une exécution de code à distance (RCE) au sein du contrôleur Ingress basé sur NGINX – une composante très répandue dans les clusters Kubernetes. Autrement dit, un attaquant pourrait exploiter cette faiblesse pour prendre le contrôle de votre cluster sans même avoir besoin d’informations d’identification préalables. Dans cet article de blog, nous allons expliquer en détail ce qu’est IngressNightmare, comment cette vulnérabilité peut être exploitée, quelles en sont les conséquences pour la sécurité de vos déploiements, et surtout comment corriger la faille et prévenir ce type de problème à l’avenir. Des études de cas concrets illustreront l’exploitation possible de la faille, et nous fournirons des bonnes pratiques DevOps pour renforcer la sécurité de vos clusters Kubernetes.
À qui s’adresse cet article ? Principalement aux développeurs et aux ingénieurs DevOps qui utilisent Kubernetes et son contrôleur Ingress NGINX en production ou en environnement de test. Même si vous n’êtes pas expert en Kubernetes, nous rappellerons les notions de base (Ingress, contrôleur, etc.) afin que tout le monde puisse suivre. Si certains concepts vous semblent nouveaux (par exemple ce qu’est un Ingress ou un admission controller), n’hésitez pas à vous référer à nos ressources de formation pour combler les lacunes. Par exemple, une excellente façon d’acquérir les bases de Kubernetes est de suivre une formation Kubernetes complète, ou encore de se familiariser avec les conteneurs via une formation Docker, et de renforcer ses compétences systèmes avec une formation Linux & Bash. Avec ces fondamentaux en tête, vous serez mieux armé pour comprendre et contrer les failles comme IngressNightmare. Entrons maintenant dans le vif du sujet.
Rappel : qu’est-ce qu’un Ingress Kubernetes et le contrôleur NGINX ?
Avant de plonger dans la vulnérabilité elle-même, clarifions le contexte technique. Kubernetes Ingress est une ressource de Kubernetes qui sert à exposer vos applications (Services) au monde extérieur, généralement via HTTP/HTTPS. Plutôt que de créer manuellement des services de type LoadBalancer ou NodePort pour chaque application, on définit un Ingress qui centralise les règles de routage : par exemple, diriger le trafic https://api.monsite.com/ vers le service backend-api et le trafic https://www.monsite.com/blog vers le service blog-front. L’Ingress permet d’associer des noms de domaine et des chemins d’URL à vos différents services internes, tout en gérant des aspects avancés comme la terminaison TLS (HTTPS), le rééquilibrage de charge (load balancing) et les hôtes virtuels basés sur les noms de domaine.
Cependant, l’objet Ingress n’est qu’une déclaration de configuration. Pour qu’il prenne effet, il faut un composant actif appelé “Ingress Controller”. C’est lui qui lit les ressources Ingress que vous avez créées et qui configure en conséquence un proxy HTTP pour acheminer le trafic. Kubernetes ne fournit pas un unique Ingress Controller par défaut – c’est un plug-in. Différentes implémentations existent (Traefik, HAProxy, Envoy, etc.), mais l’une des plus répandues est ingress-nginx, le contrôleur Ingress basé sur NGINX.
NGINX est un serveur web et proxy inverse ultra-performant et très populaire, souvent utilisé pour gérer de lourdes charges de trafic web. Le contrôleur ingress-nginx s’appuie sur NGINX en coulisses : concrètement, il déploie dans le cluster un Pod contenant NGINX, et chaque fois qu’on crée/édite un Ingress, le contrôleur met à jour la configuration d’NGINX (fichiers de config) pour refléter les nouvelles règles de routage. Ainsi, l’ingress-nginx sert de point d’entrée unique (généralement exposé via un Service de type LoadBalancer ou NodePort) qui distribue le trafic entrant selon les règles de vos Ingress. Kubernetes recommande souvent ingress-nginx comme solution de base car elle est open-source, robuste et bien supportée par la communauté.
Pourquoi parle-t-on d’un “contrôleur Ingress NGINX” ? Parce que ingress-nginx est l’implémentation utilisant NGINX. Ne pas confondre : NGINX est le logiciel serveur web, et Ingress NGINX Controller est le composant Kubernetes qui utilise NGINX pour gérer les Ingress. Si vous souhaitez approfondir vos connaissances sur Nginx (par exemple comprendre sa configuration, ses directives, son rôle comme reverse proxy), vous pouvez consulter la formation NGINX dédiée. Bien comprendre NGINX vous aidera à saisir comment un simple fichier de configuration mal maîtrisé peut ouvrir la porte à des failles de sécurité.
Maintenant que les bases sont posées, imaginez le tableau : ingress-nginx est souvent aux avant-postes du cluster, recevant tout le trafic externe. Une vulnérabilité dans ce composant est donc particulièrement critique, car elle pourrait donner à un attaquant un accès direct à la “porte d’entrée” de vos applications, voire au cluster entier. C’est exactement dans ce contexte qu’intervient la faille IngressNightmare.
IngressNightmare : cinq failles, dont une RCE critique, dévoilées en mars 2025
Le 24 mars 2025, une équipe de chercheurs en sécurité de la société Wiz a divulgué de manière coordonnée un ensemble de cinq vulnérabilités affectant le contrôleur Ingress NGINX pour Kubernetes. Ce lot de failles a été baptisé “IngressNightmare” en raison de son impact potentiellement désastreux. Parmi ces failles, la plus grave est identifiée par le code CVE-2025-1974, et c’est celle-ci qui permet une exécution de code à distance (RCE) sans authentification. Pour bien comprendre la portée de IngressNightmare, détaillons brièvement ces vulnérabilités :
- CVE-2025-24513 : vulnérabilité de traversal de répertoires liée aux fichiers de secrets d’authentification. Elle permet à un attaquant (avec certaines permissions sur l’API) d’accéder à des fichiers sensibles sur le système via un chemin malveillant fourni dans un Ingress. Gravité : moyenne.
- CVE-2025-24514 : injection de configuration via l’annotation
auth-urlnon correctement filtrée. En abusant de l’annotation qui sert normalement à définir une URL d’authentification déléguée, un attaquant avec accès à l’API peut injecter des directives NGINX arbitraires. Gravité : élevée. - CVE-2025-1097 : injection de configuration via l’annotation
auth-tls-match-cnnon filtrée. Similaire à la précédente, mais via l’option de correspondance de nom commun TLS. Gravité : élevée. - CVE-2025-1098 : injection de configuration via les annotations de mirroring (miroir du trafic) non filtrées. Là encore, un utilisateur malveillant pouvant modifier un Ingress pourrait insérer du contenu illégitime dans la config NGINX. Gravité : élevée.
- CVE-2025-1974 : exécution de code à distance via le webhook d’admission du contrôleur ingress-nginx. Cette dernière faille est considérée comme critique (score CVSS 9.8 sur 10) car exploitable sans authentification et pouvant conduire à la compromission complète du cluster Kubernetes. C’est cette CVE qui est souvent appelée simplement “IngressNightmare” car elle est le point culminant de la chaîne d’attaque.
En résumé, les failles 1 à 4 permettent, sous certaines conditions, à un attaquant ayant déjà des droits de création ou modification sur les objets Ingress (via l’API Kubernetes) d’injecter une configuration NGINX malveillante. Les conséquences immédiates de ces injections peuvent être par exemple la fuite de données sensibles. En effet, en insérant des directives spéciales dans la config, on pourrait faire en sorte qu’NGINX divulgue des informations internes, comme par exemple le token de compte de service du pod (informations potentiellement présentes dans les requêtes ou les headers d’auth). Ces quatre failles nécessitent toutefois un accès au serveur d’API Kubernetes avec des privilèges (même limités) pour créer/mettre à jour des Ingress – ce qui en restreint l’exploitation aux acteurs qui ont déjà compromis quelque peu le cluster (un développeur interne mal intentionné ou un pirate ayant dérobé des identifiants d’API par exemple).
La cinquième faille, CVE-2025-1974, est celle qui a mis tout le monde en alerte rouge. Pourquoi ? Parce qu’elle permet à un attaquant non authentifié (ni connu du cluster ni de l’API) d’obtenir une exécution de code sur le contrôleur ingress-nginx. Et comme on va le voir, cela revient pratiquement à prendre le contrôle du cluster entier. Cette vulnérabilité tire parti du mécanisme d’admission control de Kubernetes, combiné aux failles d’injection précédentes, pour contourner les protections habituelles.
Avant de détailler comment fonctionne cette RCE, notons que Kubernetes et la communauté open-source ont réagi très rapidement. Des correctifs ont été publiés le jour même de l’annonce (24 mars 2025) dans les nouvelles versions du contrôleur ingress-nginx. Ainsi :
- ingress-nginx version 1.12.1 (et supérieures) contient les correctifs pour l’ensemble des cinq CVE.
- ingress-nginx version 1.11.5 (et supérieures dans la branche 1.11) contient également ces correctifs.
Les versions vulnérables incluent toutes les versions antérieures à 1.11.0, ainsi que les versions 1.11.0 à 1.11.4 incluses, et la version 1.12.0. En clair, si votre contrôleur Ingress NGINX est en version 1.12.0, 1.11.4 ou moindre, votre cluster est potentiellement exposé à IngressNightmare. (Nous verrons plus loin comment vérifier la version de votre ingress-nginx et si votre cluster est concerné.)
Sous le capot de CVE-2025-1974 : comment une simple validation s’est transformée en RCE
Penchons-nous maintenant sur le fonctionnement technique de la faille RCE (CVE-2025-1974). Pour bien la comprendre, il faut expliquer le rôle du webhook d’admission qu’utilise le contrôleur ingress-nginx dans Kubernetes.
Le webhook d’admission ingress-nginx, qu’est-ce que c’est ?
En Kubernetes, un admission controller est un composant du plan de contrôle qui intercepte les requêtes à l’API Kubernetes juste après l’authentification et l’autorisation, et avant que les objets ne soient persistés dans etcd. Ces admission controllers peuvent valider (vérifier la conformité) ou muter (modifier) les objets qu’on essaie de créer/mettre à jour. Kubernetes permet aux extensions comme ingress-nginx de s’enregistrer auprès de l’API via un ValidatingWebhookConfiguration. Concrètement, lors de l’installation d’ingress-nginx, un webhook d’admission est configuré pour les objets Ingress : à chaque création ou modification d’un Ingress, l’API Kubernetes va appeler ce webhook (un service web spécifique tournant dans le pod ingress-nginx) afin de faire valider la ressource. Le but est d’empêcher qu’un Ingress mal formé ou avec des erreurs grossières ne soit accepté par le cluster. C’est une sorte de filet de sécurité qui, par exemple, vous avertit si vous avez mis deux fois le même hostname, ou une configuration incohérente dans votre Ingress, avant même que celui-ci ne soit appliqué.
Le webhook d’admission d’ingress-nginx est typiquement exposé en interne sous forme d’un service Kubernetes (par défaut nommé ingress-nginx-controller-admission dans le namespace ingress-nginx, port 443). Ce service n’a pas vocation à être accessible de l’extérieur du cluster (il est généralement de type ClusterIP). L’API server Kubernetes l’appelle en interne lors des validations.
À l’interne du pod ingress-nginx, comment se passe cette validation ? En inspectant le code de ingress-nginx, les chercheurs ont découvert qu’à chaque requête de validation, le contrôleur exécute la séquence suivante :
- Il appelle une fonction de validation qui génère un fichier de configuration NGINX temporaire reflétant le ou les Ingress à valider, y compris leurs annotations et options.
- Ensuite, il exécute la commande
nginx -t(test de configuration) sur ce fichier pour vérifier qu’NGINX le considère comme valide. Singinx -trenvoie “OK”, alors le webhook renvoie une réponse “allowed=true” autorisant l’objet Ingress. Si au contraire la config est invalide, le webhook rejette l’objet avec une erreur, ce qui empêche la création de l’Ingress problématique.
L’idée paraissait bonne : utiliser la capacité native d’NGINX à valider sa configuration pour empêcher qu’une mauvaise config (via une annotation d’Ingress erronée par exemple) ne cause des soucis à l’exécution. Le hic : l’outil de test de config nginx -t n’était pas censé être exploité à des fins malveillantes… Or, les chercheurs ont trouvé un moyen ingénieux de faire exécuter du code arbitraire à nginx -t en lui faisant avaler une configuration spécialement conçue.
Du test de config à l’exécution de code arbitraire
Comment peut-on obtenir une exécution de code via un simple test de configuration ? Cela semble contre-intuitif, mais c’est rendu possible par l’enchaînement de plusieurs choses :
- Injection de directives NGINX malicieuses : grâce aux failles d’annotation (CVE-2025-24514, 1097, 1098), un attaquant qui peut soumettre un Ingress (ou provoquer son envoi au webhook) a la possibilité d’insérer du texte arbitraire dans le fichier de configuration NGINX temporaire. Par exemple, en abusant de l’annotation
auth-urlnon filtrée, on peut faire en sorte que la config générée contienne des lignes totalement contrôlées par l’attaquant. - Fonctionnalités avancées (et dangereuses) d’NGINX : NGINX possède des directives très puissantes, dont certaines permettent d’interagir avec le système de fichiers ou de charger des modules externes. Dans le cadre de l’attaque IngressNightmare, il a été rapporté que les assaillants peuvent notamment utiliser la directive
ssl_engine. Normalement,ssl_enginesert à indiquer un moteur cryptographique matériel (par ex. une carte HSM) via une librairie .so. Or, rien n’empêche de l’utiliser pour charger une librairie arbitraire – par exemple, un fichier .so contenant du code malveillant. - Upload d’un fichier malveillant via NGINX : Vous vous demandez peut-être comment l’attaquant pourrait déposer une librairie .so sur le système de fichiers du pod ingress-nginx sans y avoir accès ? C’est là qu’entre en jeu un tour astucieux. NGINX, lorsqu’il traite des requêtes HTTP, utilise par défaut un mécanisme de buffering pour stocker temporairement les corps de requête volumineux sur disque (pour optimiser la RAM). Un attaquant peut donc forcer NGINX (le serveur web du contrôleur) à écrire un contenu binaire de son choix sur le disque du pod, simplement en envoyant une requête HTTP avec un corps très lourd (par exemple via une requête malformée ou un appel spécifique aux endpoints du webhook). Ce contenu peut être l’image binaire d’une librairie partagée (.so). Ensuite, grâce à une particularité des fichiers sous Linux, même si NGINX “supprime” le fichier temporaire après usage, le fichier reste accessible via son descripteur /proc tant que le processus NGINX qui l’a ouvert ne l’a pas totalement fermé. Les chercheurs de Wiz ont démontré qu’il est possible de référencer le fichier malveillant via un chemin spécial
/proc/<pid>/fd/<fd>, et d’injecter ce chemin dans la config NGINX malveillante. - Chaînage final : L’attaquant combine alors ces éléments : il injecte dans la configuration NGINX temporaire une directive
ssl_enginepointant vers le fichier .so malveillant (via le chemin /proc trick), puis il déclenche la validation. Le webhook écrit la config, lancenginx -t. Ce dernier, en parcourant la config, voitssl_engine /proc/....et obéit en chargeant la librairie malveillante. Cette librairie contient un code qui s’exécute immédiatement (par exemple un shell inversé qui se connecte vers l’attaquant). Et voilà : l’attaquant a maintenant du code exécuté dans le processus du contrôleur ingress-nginx, c’est-à-dire au sein du pod.
Ce scénario paraît complexe, mais il revient à ceci : en soumettant une configuration habilement forgée, l’outil de test de config d’NGINX devient l’instrument de l’attaquant pour exécuter du code dans le cluster. Ce type d’exploitation est assez sophistiqué et montre le haut niveau d’expertise des chercheurs qui l’ont découverte.
Pourquoi “non authentifié” ? – La surface d’attaque du webhook
Un point essentiel de CVE-2025-1974 est qu’il est exploitable sans authentification sur l’API Kubernetes. En effet, contrairement aux failles d’annotation qui nécessitent de pouvoir créer un Ingress via l’API (ce qui requiert des droits Kubernetes), ici l’attaquant n’a pas besoin de passer par l’API server du cluster. Il lui suffit de pouvoir atteindre le service du webhook d’admission ingress-nginx et de lui envoyer une requête de validation comme si c’était l’API server. Or, par conception, le webhook d’admission ne requiert pas d’authentification car il est censé être appelé uniquement par le composant de l’API Kubernetes à l’intérieur du cluster (qui est de confiance). C’est un service interne sans authentification.
- Depuis l’extérieur du cluster : Normalement, le service
ingress-nginx-controller-admissionn’est pas exposé hors du cluster (type ClusterIP sans LoadBalancer). Il serait donc difficile pour un attaquant externe d’y accéder, sauf mauvaise configuration. Cependant, il arrive que par erreur ou besoin de debug, ce service soit exposé (par exemple, un utilisateur aurait pu le changer en NodePort, ou ouvrir son port via un Ingress ou autre). Si c’est le cas, n’importe quel internaute pourrait directement adresser ce webhook et potentiellement lancer l’attaque. C’est un scénario improbable mais catastrophique si c’est en place. - Depuis l’intérieur du cluster : Le cas de figure bien plus courant est celui où l’attaquant a déjà compromis un conteneur dans votre cluster ou déployé un pod malveillant. Imaginons un acteur malveillant qui a réussi à exécuter du code dans un de vos pods applicatifs (via une faille applicative, injection SQL, RCE dans votre code, etc.). Ce pod est sur le réseau interne du cluster (le réseau Pod). Par défaut, en l’absence de politiques réseau restrictives, tout pod peut parler à n’importe quel service ou pod dans le cluster. Donc, depuis ce pod compromis, l’attaquant peut tout à fait envoyer des requêtes vers
ingress-nginx-controller-admission.ingress-nginx.svc.cluster.localsur le port 443. Bingo : il a accès au webhook, sans authentification, depuis l’intérieur. Ce scénario ne requiert aucune permission Kubernetes supplémentaire – juste la capacité à communiquer sur le réseau interne, ce qui est le cas de tout pod par défaut. De plus, dans beaucoup d’environnements cloud ou d’entreprises, le réseau Pod peut être accessible depuis d’autres endroits (par exemple, les machines virtuelles du VPC, ou un VPN interne). Il suffit donc parfois d’avoir un accès réseau interne (pas forcément un accès K8s) pour potentiellement atteindre le webhook.
En résumé, si un attaquant trouve un moyen d’exécuter du code sur un de vos pods (n’importe lequel), ou même simplement d’envoyer des paquets réseau depuis une VM du réseau interne, il peut exploiter CVE-2025-1974 pour prendre le contrôle du contrôleur Ingress. C’est ce qui rend cette faille particulièrement dangereuse : elle supprime la barrière de l’authentification/autorisation Kubernetes habituelle. Même un service très cloisonné sans accès API pourrait servir de tremplin.
Un accès au contrôleur Ingress = la clé du royaume
Une fois l’attaquant en mesure d’exécuter du code dans le pod du contrôleur ingress-nginx, que peut-il faire ? Malheureusement, énormément de choses. Par défaut, le déploiement ingress-nginx dans Kubernetes utilise un compte de service qui a un rôle relativement puissant. En particulier, le contrôleur Ingress a besoin de lire les secrets TLS (certificats) associés aux Ingress pour configurer HTTPS. Pour ce faire, dans la configuration standard, un ClusterRole lui confère l’accès en lecture à tous les Secrets de tout le cluster. Cela signifie que dès que l’attaquant a un shell dans le pod ingress-nginx, il peut exécuter des commandes kubectl (ou interroger l’API) via le token du service account du contrôleur, et aspirer toutes vos clés TLS, mots de passe, tokens d’accès stockés en tant que Secret Kubernetes. Il peut aussi potentiellement modifier des Ingress, créer de nouvelles ressources, etc., selon l’étendue exacte des permissions du contrôleur (souvent, en lecture c’est très large, en écriture plus limité mais rien n’empêche d’augmenter les privilèges par la suite si des credentials sensibles sont trouvés).
En clair, CVE-2025-1974 permet à un attaquant déterminé de prendre le contrôle total du cluster avec un point d’entrée très faible (une simple présence réseau interne). C’est pour cela que son score de criticité frôle la note maximale (9.8/10) et qu’on parle de cluster takeover. On peut comparer l’impact à une compromission de la machine maître dans un cluster non-managé, ou d’un rôle cluster-admin : toutes les données, tous les services et applications hébergés risquent d’être compromis.
Études de cas : comment la faille peut être exploitée en pratique
Parlons concrètement de scénarios où IngressNightmare pourrait être exploité par des acteurs malveillants. Il est toujours utile de visualiser la chaîne d’attaque du point de vue d’un “hacker” pour bien appréhender les risques.
- Scénario 1 : Compromission d’un pod applicatif suivie d’une escalade. Imaginons une application web vulnérable déployée sur votre cluster (par exemple, une application qui subit une injection de commande ou une désérialisation non sécurisée). Un attaquant exploite cette vulnérabilité et obtient un accès shell dans le conteneur de cette application. Il se retrouve donc à l’intérieur de votre cluster, sur le réseau Pod. À ce stade, il a peut-être un accès limité (il est utilisateur non privilégié dans le conteneur, pas d’accès Kubernetes direct), mais il peut scanner l’environnement. Il découvre, grâce au DNS interne, qu’il y a un service
ingress-nginx-controller-admissionsur le port 443. Il envoie alors une requête spécialement construite vers ce service, enchaînant l’injection de configuration et l’exploit RCE détaillé plus haut. En quelques secondes, il obtient un accès à un nouvel hôte – le pod du contrôleur Ingress. Depuis là, il vole le token du service account du contrôleur, le monte dans kubectl, et le cluster entier est compromis : il peut lire tous les secrets, éventuellement modifier des configurations, ou déployer d’autres charges malveillantes plus persistantes. Ce scénario montre comment une petite faille applicative initiale peut mener, via IngressNightmare, à un désastre global, si des mesures de défense en profondeur ne sont pas en place. - Scénario 2 : Webhook exposé par erreur sur internet. Supposons maintenant un cluster dont la configuration réseau a été faite à la va-vite. Par exemple, un administrateur a exposé tous les services du namespace
ingress-nginxvia un mécanisme d’entrée (il aurait pu confondre et créer un Ingress pour le service d’admission, ou changer son type en LoadBalancer). Résultat, l’URL du webhook d’admission ingress-nginx est accessible publiquement (par exemple sur un port spécifique du load balancer du cluster). Un attaquant, ou même un scanner automatisé parcourant les plages IP cloud, tombe sur cette porte ouverte. Il n’a même pas besoin de pénétrer un conteneur d’abord – il envoie directement sa charge malveillante au webhook via Internet. Celui-ci, ne distinguant pas que la requête ne vient pas de l’API server légitime, traite la demande, teste la config NGINX, et se fait exploiter. L’attaquant obtient un accès au pod ingress-nginx et peut aller plus loin comme précédemment. Ici, en une étape l’attaquant passe d’internet à cluster-admin, ce qui est assez effrayant. Heureusement, ce cas de figure nécessite une sérieuse erreur de configuration de la part des opérateurs (on ne devrait jamais exposer un webhook interne), mais de telles erreurs arrivent, surtout dans des phases de test ou par confusion. - Scénario 3 : Un utilisateur interne malveillant ou un pentest interne. Pensez à un contexte d’entreprise où plusieurs équipes partagent le même cluster (multi-tenant). Chaque équipe a accès à un namespace pour déployer ses applications, peut-être avec le droit de créer des Ingress pour exposer leurs services. Un employé malveillant appartenant à une de ces équipes pourrait créer un Ingress intentionnellement piégé exploitant les failles d’annotation (par ex. mettre une valeur d’annotation très exotique visant à injecter du code). Grâce à la CVE-2025-1974 couplée à ces injections, il n’a pas besoin d’être cluster-admin pour compromettre le cluster. Même un rôle de développeur avec accès limité à un namespace peut suffire pour amorcer l’attaque. Ce scénario montre que la menace peut aussi venir de l’intérieur, ou d’un acteur ayant dérobé les identifiants d’un compte utilisateur lambda sur le cluster. Encore une fois, la faille supprime beaucoup de barrières de sécurité habituelles.
Chacun de ces scénarios aboutit à la même conséquence : le pod ingress-nginx compromis, l’attaquant s’octroie des privilèges élevés et cause une fuite de données ou un sabotage. Des exemples concrets de ce qu’un attaquant pourrait faire incluent : aspirer toutes les variables d’environnement de vos pods (contenant potentiellement des mots de passe), détourner le trafic des applications (en modifiant les règles d’Ingress pour rediriger vers un serveur sous son contrôle), déployer un malware ou ransomware sur vos conteneurs, ou encore rendre indisponibles vos services (attaque de type déni de service interne).
Il convient de souligner qu’au moment de la divulgation de IngressNightmare, il n’y avait pas encore de code d’exploitation publié publiquement ni de preuve d’exploitation active connue dans la nature. Cependant, il serait imprudent de compter sur cela : ce type de faille attire énormément l’attention, et tôt ou tard, des attaquants en développeront des outils d’exploitation automatisés. Le fait qu’il n’y ait pas de signature évidente (indicateur de compromission) rend d’ailleurs la détection délicate : une requête au webhook et l’exécution de nginx -t ne sont pas facilement distinguables d’un comportement normal du système, surtout si l’attaquant nettoie ses traces après coup. Il est donc crucial d’agir en prévention, pas en réaction.
Après avoir dressé ce sombre tableau des risques, passons aux bonnes nouvelles : des correctifs existent et des mesures peuvent être prises pour protéger votre cluster.
Que faire immédiatement ? – Vérification et correctifs de IngressNightmare
Si vous utilisez Kubernetes avec ingress-nginx, la première question à se poser est : Mon cluster est-il vulnérable à IngressNightmare ? Voici une liste d’actions à entreprendre sans délai :
1. Vérifiez si votre cluster utilise le contrôleur Ingress NGINX et quelle version.
Il est possible que vous n’utilisiez pas du tout ingress-nginx (par exemple si vous utilisez Traefik, Istio, ou un cloud Load Balancer direct). Pour vérifier la présence d’ingress-nginx, utilisez la commande :
kubectl -n ingress-nginx get deploy ingress-nginx-controller -o yaml | grep "image:"
Celle-ci liste les pods dont le label correspond à ingress-nginx (valeur par défaut). Si aucune ressource n’est retournée, vous n’utilisez probablement pas ingress-nginx dans votre cluster – vous n’êtes donc pas concerné par ces failles (du moins pas par celle-ci, mais restez vigilant aux autres composants). Si en revanche vous voyez un ou plusieurs pods (souvent dans un namespace nommé ingress-nginx), alors continuez l’analyse.
Pour connaître la version du contrôleur, inspectez éventuellement l’image Docker utilisée par le pod ingress-nginx. Par exemple :
kubectl -n ingress-nginx get deploy ingress-nginx-controller -o yaml | grep "image:"
Cherchez un tag du style v1.12.0 ou v1.11.3 etc. S’il s’agit d’une version ≤ 1.11.4, ou de la 1.12.0, votre déploiement est vulnérable. Si c’est 1.11.5, 1.12.1 ou plus récent, vous devriez déjà avoir les correctifs (mais assurez-vous que cela a été correctement déployé).
2. Mettez à jour ingress-nginx vers une version corrigée.
La solution la plus simple et la plus sûre est de mettre à jour le contrôleur Ingress NGINX vers la dernière version stable corrigée. Au minimum, v1.11.5 ou v1.12.1. Idéalement, passez en dernière version disponible de la branche stable. Cette opération dépend de comment vous avez installé ingress-nginx :
- Si vous avez installé via Helm, vous pouvez mettre à jour la release Helm vers la version du chart qui inclut ingress-nginx corrigé (chart ingress-nginx v4.11.5 ou v4.12.1 par exemple, correspondant aux versions de contrôleur fixes). Par exemple :
helm upgrade --namespace ingress-nginx ingress-nginx ingress-nginx/ingress-nginx --version 4.12.1. - Si vous avez installé via des manifests YAML (déploiement manuel), récupérez le dernier manifest officiel depuis le dépôt GitHub Kubernetes/ingress-nginx (branché sur la version stable) et appliquez-le (
kubectl apply -f https://raw.githubusercontent.com/...). Assurez-vous que l’image du contrôleur est bien la nouvelle version. - Si vous utilisez un service managé (AKS, EKS, GKE) : ces services ne déploient pas ingress-nginx par défaut, mais votre équipe a pu le déployer manuellement ou via Helm. Certaines distributions managées fournissent aussi un contrôleur d’ingress “maison” ou un add-on. Vérifiez dans la documentation de votre fournisseur s’il a communiqué sur IngressNightmare. Par exemple, AWS, Azure et Google ont émis des bulletins conseillant de mettre à jour si vous utilisez ingress-nginx dans leur environnement. Appliquez les recommandations spécifiques le cas échéant.
La mise à jour doit idéalement être testée en environnement de staging avant production. Toutefois, vu l’urgence, ne tardez pas : mieux vaut une courte interruption contrôlée pour upgrade que de laisser la porte ouverte aux attaquants. Les versions 1.11.5+ et 1.12.1+ corrigent toutes les failles mentionnées.
3. Si la mise à jour immédiate n’est pas possible, appliquez des mesures d’atténuation temporaires.
Parfois, mettre à jour un composant critique peut nécessiter des validations ou des fenêtres de maintenance. Si vous ne pouvez pas patcher dans les toutes prochaines heures, vous devez réduire la surface de risque de CVE-2025-1974 en attendant. L’action la plus efficace est de désactiver le webhook d’admission vulnérable du contrôleur ingress-nginx, le temps de mettre à jour. Cela empêchera l’exploitation de la RCE, au prix de désactiver la validation automatique des Ingress (ce qui est un compromis tout à fait acceptable temporairement).
Voici comment procéder en fonction de votre installation :
- Cas d’une installation via Helm : vous pouvez redéployer en ajustant la valeur Helm
controller.admissionWebhooks.enabled=false. Par exemple :helm upgrade ingress-nginx ingress-nginx/ingress-nginx --set controller.admissionWebhooks.enabled=false .... Cette option va désactiver l’ensemble du mécanisme de webhook d’admission pour ingress-nginx. - Cas d’une installation manuelle (manifests) : deux étapes sont nécessaires :
- Supprimez l’objet
ValidatingWebhookConfigurationdu cluster. Il s’appelle généralementingress-nginx-admission. Vous pouvez le supprimer via :kubectl delete ValidatingWebhookConfiguration ingress-nginx-admission. Ainsi, l’API Kubernetes ne contactera plus le service de webhook lors des créations d’Ingress. - Éditez le déploiement du contrôleur ingress-nginx (
kubectl edit deploy ingress-nginx-controller -n ingress-nginx). Dans la spécification du conteneur, trouvez la ligne de commande (args) qui contient--validating-webhook=...et retirez entièrement cet argument (ou passez-le àfalsesi possible). Cette modification empêchera le contrôleur de mettre en place à nouveau le webhook d’admission. Redémarrez le pod du contrôleur après avoir modifié la config pour assurer la prise en compte.
- Supprimez l’objet
Après ces changements, le contrôleur ingress-nginx continuera de fonctionner pour router le trafic, mais ne validera plus les Ingress à la volée. Cela veut dire que si vous appliquez un Ingress mal formé, il pourrait potentiellement causer des erreurs ou un dysfonctionnement de NGINX (puisque la couche de validation n’est plus là pour le bloquer). Cependant, c’est un moindre mal comparé à la possibilité d’exécution de code arbitraire. N’oubliez pas de réactiver ce mécanisme une fois la mise à jour appliquée, car il offre une protection utile en temps normal. Après avoir patché, vous pourrez soit repasser le paramètre Helm enabled=true, soit ré-appliquer le manifest du webhook fourni avec la nouvelle version.
- Restriction réseau: une autre mitigation importante consiste à s’assurer que le service du webhook d’admission n’est pas accessible depuis l’extérieur et à restreindre son accessibilité interne. Vérifiez que
ingress-nginx-controller-admissionest bien de type ClusterIP sans IP externe. Si par malheur il était en NodePort ou LoadBalancer, changez cela immédiatement pour le rendre interne. De plus, au sein même du cluster, si vous avez la possibilité de mettre en place des NetworkPolicies, faites-le : vous pouvez créer une policy qui autorise uniquement le composant API server à communiquer avec le service d’admission, et bloque tout autre trafic Pod->Service sur celui-ci. Par exemple, si vous connaissez l’IP cluster interne de l’API server ou un label unique qu’il porte (certains déploient l’API server en tant que pod, sinon ce n’est pas un pod mais un composant maître), autorisez seulement ce dernier. Sinon, autorisez au moins uniquement le namespacekube-systemvers le namespaceingress-nginxsur le port 443 du service. En somme, implémentez une sorte de micro-segmentation pour éviter que n’importe quel pod compromis puisse discuter avec le webhook. Bien que cela n’enlève pas la faille, cela en complique énormément l’exploitation par un acteur opportuniste.
4. Surveillez les correctifs de vos fournisseurs cloud ou distributions.
Si vous utilisez des clusters managés ou des distributions spécifiques (OpenShift, Rancher, etc.), tenez compte de leurs avis de sécurité. Par exemple, AWS a publié un avis conseillant aux utilisateurs d’EKS qui auraient installé ingress-nginx de mettre à jour; Azure AKS et GCP ont fait de même. Certaines plateformes proposent un correctif automatique ou un patch intermédiaire. Assurez-vous d’appliquer les mises à jour recommandées.
5. Informez votre équipe et planifiez une analyse post-mortem (si nécessaire).
Si votre cluster était vulnérable, il est légitime de se demander si la faille a pu être exploitée avant que vous ne corrigiez. Pour l’instant, il n’existe pas de signature évidente, mais vous pouvez vérifier certains éléments :
- Parcourez les logs des pods ingress-nginx sur les derniers jours à la recherche de comportements inhabituels. Par exemple, des lignes dans les logs d’admission qui auraient validé une configuration juste avant un plantage ou un redémarrage du pod (un crash pourrait indiquer une tentative d’exploitation ratée).
- Si vous avez des outils de sécurité intégrés (IDS/IPS, SIEM avec monitoring de la kube-audit, ou agent de sécurité dans les conteneurs), voyez s’ils ont relevé des événements anormaux autour du 24 mars 2025 ou après (date de divulgation publique).
- Rien ne remplace un examen minutieux en cas de doute : si vous suspectez une compromission, envisagez de faire tourner des outils d’analyse forensique dans le cluster, ou redeployez un cluster sain en extrayant les données des secrets du précédent.
En suivant ces étapes, vous devriez avoir colmaté la brèche. Mais combler la faille ne suffit pas toujours : il faut aussi tirer les leçons pour l’avenir et renforcer globalement la sécurité de vos environnements Kubernetes.
Renforcer la sécurité : comment prévenir ce genre de problèmes à l’avenir
IngressNightmare est un rappel brutal que, même dans l’écosystème cloud-native, une simple faiblesse logicielle peut mettre à mal l’infrastructure la plus moderne. Voici quelques bonnes pratiques et mesures préventives pour éviter que ce type de mésaventure ne se reproduise ou pour en limiter l’impact :
1. Maintenez vos composants à jour et appliquez les correctifs de sécurité rapidement.
Cela peut sembler évident, mais dans la précipitation des projets, on oublie parfois de mettre à jour d’importants composants comme ingress-nginx. Abonnez-vous aux flux d’annonces de sécurité de Kubernetes et des projets associés. Par exemple, la Kubernetes Security Committee publie des alertes sur les failles critiques. Dès qu’une annonce concernant un composant que vous utilisez paraît, planifiez un patching en urgence. Mettre en place une veille technologique est crucial. Si vous gérez beaucoup de clusters, regardez du côté des outils d’automatisation (ansible, flux GitOps, etc.) pour faciliter les upgrades simultanés. Une plateforme CI/CD bien rodée avec pipeline de déploiement Kubernetes peut vous permettre de redéployer rapidement des composants à jour. Si vous souhaitez professionnaliser votre approche CI/CD et DevOps, songez à vous former sur les outils comme GitLab CI/CD, Jenkins, Terraform, etc., qui peuvent aider à gérer l’infrastructure as code. (Par exemple, Dyma propose des formations dédiées à Docker et Kubernetes comme mentionné, mais aussi Ansible, Terraform et d’autres, ce qui peut vous aider à mettre en place un déploiement automatisé et reproductible de vos clusters avec une gestion facilitée des mises à jour.)
2. Segmentez le réseau de votre cluster (Principe de moindre confiance).
Par défaut, Kubernetes adopte un modèle de réseau plat où tout pod peut communiquer avec tout autre. Cela facilite la découverte de services, mais côté sécurité ce n’est pas idéal. Implémentez des NetworkPolicies pour cloisonner vos pods. Par exemple, il est rarement nécessaire qu’un pod applicatif communique avec le pod du contrôleur Ingress sur le port d’admission. Vous pourriez définir une policy qui interdit toute connexion vers le pod du contrôleur Ingress, sauf depuis l’API server. De manière générale, réfléchissez aux flux réseau réellement nécessaires : les bases de données n’ont pas besoin de recevoir du trafic de n’importe quel service, etc. En segmentant, vous réduisez les possibilités de mouvement latéral pour un attaquant qui aurait compromis un point. Ainsi, même si un pod est compromis, il ne pourra pas automatiquement scanner et atteindre tous les autres services sensibles du cluster. Le principe du Zero Trust s’applique aussi en intra-cluster.
3. Limitez les permissions accordées aux composants systèmes (Principe du moindre privilège).
L’affaire IngressNightmare a mis en lumière le fait que le contrôleur ingress-nginx avait un rôle très permissif (lecture de tous les secrets cluster-wide). Posez-vous la question : votre ingress controller a-t-il vraiment besoin d’accéder à tous les secrets ou toutes les namespaces ? Peut-être pourriez-vous restreindre son rôle Kubernetes pour qu’il ne puisse lire que les secrets TLS du namespace où il est déployé, ou ceux portant un label particulier. Idem pour d’autres composants : Etcd n’a pas besoin de tourner en root dans un conteneur, metrics-server n’a pas besoin d’avoir des droits escaladés, etc. Kubernetes RBAC est un outil puissant, encore faut-il l’utiliser finement. Prenez le temps d’auditer les ClusterRole/Role et ClusterRoleBindings en place : supprimez ou réduisez ceux qui sont trop larges. Créez des comptes de service dédiés avec juste ce qu’il faut comme permissions pour chaque composant. Moins un service a de droits, plus l’impact d’une compromission de ce service sera contenu.
Dans le cas concret d’ingress-nginx, la version patchée a modifié son approche de validation (elle ne lance plus nginx -t de la même manière risquée). Mais on peut aussi envisager à l’avenir que l’Ingress Controller utilise un service account avec moins de droits (par exemple, uniquement lecture des secrets TLS du namespace ingress-nginx). Si ce n’est pas faisable en l’état, surveillez les évolutions du projet – ou contribuez-y.
4. Désactivez ou restreignez les fonctionnalités non utilisées.
Les failles d’IngressNightmare impliquent des fonctionnalités comme l’auth request, le TLS externe, le mirroring, et la possibilité d’injecter des snippets de configuration NGINX via des annotations. Si vous n’utilisez pas ces fonctions, il est souvent préférable de les désactiver. Par exemple, ingress-nginx offre un paramètre global pour désactiver les “snippet” d’annotations personnalisées (car par le passé déjà, des vulnérabilités similaires ont conduit les mainteneurs à déconseiller fortement leur usage). De même, si vous n’utilisez pas la fonctionnalité de mirroring de trafic, supprimez le module ou bloquez l’annotation correspondante via une politique d’admission. Chaque composant ou module en moins, c’est une surface d’attaque en moins. En sécurité informatique, la simplicité est votre alliée : plus un système est épuré, moins il y a de recoins à exploiter. Pensez minimalisme dans vos configurations Kubernetes. Par exemple, si vos Ingress n’ont pas vocation à utiliser l’authentification externe, vous pourriez carrément rejeter tout Ingress qui tenterait de mettre une annotation auth-url via un Admission Controller dédié ou un outil comme OPA/Gatekeeper, afin d’éviter qu’un développeur (ou un attaquant via un compte compromis) n’expose sans le vouloir une future faille.
5. Surveillez activement votre cluster.
Même avec les meilleures protections, le risque zéro n’existe pas. Il est donc impératif de disposer de mécanismes de détection en cas d’activité suspecte. Voici quelques pistes :
- Logs et audit Kubernetes : Activez l’audit logging de l’API Kubernetes si ce n’est pas déjà fait. Cela vous permettra de voir les requêtes inhabituelles, par exemple un pod qui lit tous les secrets soudainement. De même, surveillez les logs des pods système (ingress controller, scheduler, kube-proxy, etc.). Un redémarrage inattendu ou un log inhabituel (“unexpected config” ou autre) doit être investigué.
- Détection d’intrusion dans les conteneurs : Des solutions open-source comme Falco peuvent monitorer en temps réel le comportement de vos conteneurs et remonter des alertes si un conteneur fait quelque chose d’anormal (ex: un processus bash qui apparaît dans le pod ingress-nginx, ce qui serait très suspect !). Dans IngressNightmare, après exploitation, l’attaquant a un shell dans ingress-nginx – c’est typiquement le genre de choses qu’un outil de sécurité comportementale peut repérer (processus inhabituel, connexion sortante étrange, etc.).
- Outils de benchmark sécurité : En complément, vous pouvez régulièrement passer votre cluster au crible de scanners comme kube-bench (qui vérifie les bonnes pratiques de configuration Kubernetes) ou kube-hunter (qui tente de détecter des failles courantes en simulant un attaquant). Ces outils vous aideront à identifier des points faibles, par exemple “Le port du webhook X est accessible” ou “Tel composant a des privilèges admin”.
- Tests de pénétration et bug bounty internes : Rien ne vaut un test d’intrusion sur votre propre infra pour découvrir des failles avant les attaquants. Si vous avez une équipe de sécurité, organisez des exercices de Red Team sur vos clusters Kubernetes. Ils pourraient, qui sait, découvrir une exposition inattendue ou une mauvaise configuration avant qu’un vrai attaquant n’en profite.
6. Sensibilisez et formez vos équipes.
La sécurité Kubernetes est un domaine en constante évolution. Ce qui était vrai hier (ex : “mon Ingress, ça tourne, pas besoin d’y toucher”) peut être remis en cause par une nouvelle menace. Il est important que les développeurs, DevOps et ingénieurs infra comprennent bien les risques et les bonnes pratiques associés. Par exemple, tout le monde ne savait peut-être pas qu’un pod compromis pouvait contacter tous les autres pods par défaut – cette prise de conscience peut pousser à adopter spontanément plus de restrictions. De même, bien connaître NGINX et son fonctionnement interne peut mener à configurer plus prudemment les annotations ou modules activés. Encouragez la montée en compétence sur ces sujets : des formations dédiées (comme la formation Kubernetes pour les bases de l’orchestration, ou des modules avancés sur la sécurité dans Kubernetes) sont un investissement précieux pour éviter les erreurs de configuration.
On peut aussi suggérer aux équipes de contribuer aux communautés open-source ou au moins de les suivre de près. Par exemple, ingress-nginx étant un projet communautaire, être présent sur son Slack ou GitHub peut donner des indications en amont sur les problèmes découverts.
Enfin, mettez en place une culture du partage d’information : si vous êtes au courant d’une faille critique, assurez-vous que tous les collègues concernés le sachent rapidement (via Slack interne, mail, réunion flash). Dans le cas d’IngressNightmare, plus l’information circule vite, plus les correctifs peuvent être appliqués vite, réduisant la fenêtre d’exposition.
Conclusion : un réveil difficile, mais salutaire pour la communauté Kubernetes
“IngressNightmare” porte bien son nom – ce cauchemar a montré qu’une suite de petites vulnérabilités pouvait, une fois combinées, ouvrir en grand l’accès à un cluster Kubernetes entier. Cette faille RCE dans le contrôleur NGINX Ingress nous rappelle à quel point la sécurité doit rester une préoccupation de tous les instants lorsque l’on gère des infrastructures cloud-native.
La bonne nouvelle dans cette histoire est la réactivité de la communauté : les mainteneurs d’ingress-nginx, aidés par les chercheurs de Wiz et l’équipe de sécurité Kubernetes, ont fourni des patchs le jour même de l’annonce, limitant ainsi l’exposition. Si vous avez suivi les recommandations de cet article, vous avez normalement pu évaluer votre propre exposition, appliquer les correctifs ou mitigations nécessaires, et renforcer vos défenses pour l’avenir.
Ne perdez pas de vue que d’autres failles critiques pourront survenir – Kubernetes et son écosystème évoluent vite, et la complexité est telle que des bugs de sécurité sont inévitables. L’important est de garder une posture pro-active : rester informé, maintenir ses systèmes à jour, appliquer le principe de moindre privilège, segmenter, monitorer et former continuellement les équipes. À ce titre, n’hésitez pas à partager cet article avec vos collègues développeurs, ops, DevSecOps : plus nous serons nombreux à comprendre ces enjeux et à y remédier rapidement, plus nos environnements seront sûrs. La sécurité est l’affaire de tous, du code de l’application jusqu’au déploiement Kubernetes.
En restant vigilants et en apprenant de ce type de vulnérabilité, nous pourrons transformer ce cauchemar en leçon apprise. Kubernetes est un outil formidable, et avec les bonnes pratiques, il peut offrir un niveau de sécurité robuste – à condition de ne pas le considérer comme acquis. Prenez soin de vos clusters, continuez à vous former (que ce soit via des formations DevOps et Cloud ou par l’expérience sur le terrain), et vous dormirez sur vos deux oreilles… à l’abri des prochains “nightmares” qui pourraient surgir. Bon déploiement en sécurité à tous !