Retour
2026/11/10
Kyverno CVE-2026-124440 : quand le moteur de politiques devient la voie d’accès à l’administration du cluster
Dans Kyverno 1.19.1, un locataire autorisé à écrire des politiques dans un namespace peut devenir administrateur du cluster. Mécanisme et points à vérifier.
De nombreuses équipes utilisent Kyverno pour isoler les locataires (tenants) dans Kubernetes. Kyverno vérifie chaque objet au regard des politiques avant que le serveur d’API ne l’enregistre, et peut permettre aux propriétaires d’un namespace d’écrire leurs propres politiques pour ce namespace. La CVE-2026-124440, publiée le 8 novembre 2026, montre comment cette délégation peut échouer. Dans Kyverno 1.19.1, un locataire qui n’a le droit de créer des politiques que dans son propre namespace peut amener Kyverno à agir en dehors de ce namespace et, de proche en proche, obtenir les droits d’administrateur du cluster.
Le correctif est disponible depuis le 20 octobre dans Kyverno 1.19.2. Les clusters qui n’ont pas installé cette version restent exposés. Cet article explique ce qui n’a pas fonctionné, comment se déroule l’élévation de privilèges et ce qu’il faut vérifier dans vos propres clusters.
Points clés
- La CVE-2026-124440 (avis GitHub GHSA-39w8-hv5g-f73w) concerne Kyverno 1.19.1. Elle est corrigée dans la version 1.19.2. L’enregistrement CVE lui attribue un score de 9.4 selon CVSS 4.0 et de 9.9 selon CVSS 3.1.
- L’attaquant a seulement besoin du droit de créer une Policy Kyverno de portée namespace dans son propre namespace.
- L’apiCall de la politique s’exécute avec le ServiceAccount de l’admission controller de Kyverno, qui peut lire d’autres namespaces et créer des webhooks d’admission à l’échelle du cluster. Cette voie mène aux droits d’administrateur du cluster.
- L’avis n’indique aucune solution de contournement. Passez à la version 1.19.2, puis vérifiez qui peut créer des politiques et quels webhooks existent.
- Aucune exploitation active n’a été signalée dans les sources que nous avons consultées.
Ce que la restriction de namespace devait garantir
Les politiques Kyverno peuvent récupérer des données depuis l’API Kubernetes pendant l’évaluation d’une requête. Cette fonctionnalité s’appelle apiCall : une règle indique un urlPath, Kyverno appelle le serveur d’API et le résultat alimente la règle. L’appel est effectué avec le propre ServiceAccount de Kyverno, et non avec les droits de la personne qui a écrit la politique.
Pour les ClusterPolicies, qui s’appliquent à tout le cluster et sont écrites par les administrateurs de la plateforme, ce comportement est attendu. Pour les Policies de portée namespace, que les locataires peuvent être autorisés à écrire, c’est un risque. Des avis antérieurs (GHSA-c5qq-7g2q-cpqp et GHSA-5qq8-67g6-4h2w) avaient montré qu’une Policy de portée namespace pouvait utiliser apiCall pour lire d’autres namespaces ou écrire des objets de portée cluster. Kyverno 1.19.1, publié le 10 septembre 2026, a ajouté une « restriction de namespace » (namespace clamp) : avant d’exécuter l’appel, Kyverno vérifie que le chemin reste à l’intérieur du namespace de la politique.
Là où la vérification et l’action divergent
Dans la version 1.19.1, la restriction ne vérifiait pas la chaîne réellement envoyée. Selon l’avis, elle décodait l’encodage-pourcent de urlPath, normalisait le résultat (de sorte que les segments .. soient résolus) et vérifiait le namespace dans cette copie nettoyée. La requête elle-même était ensuite envoyée avec le chemin brut d’origine.
Cela fonctionne tant que le décodage réussit. Mais si le chemin contient une séquence d’échappement mal formée, par exemple un % isolé dans une chaîne de requête en fin de chemin, le décodage échoue. Dans ce cas, le code de la version 1.19.1 se rabattait sur la vérification de la chaîne brute, toujours encodée. Le serveur d’API, lui, n’a pas ce mécanisme de repli. Il décode entièrement le chemin et achemine la requête. La restriction voit donc le namespace du locataire, tandis que le serveur d’API voit des segments .. encodés qui en sortent, vers un autre namespace ou vers une collection de portée cluster.
L’avis souligne qu’il s’agit d’une catégorie d’entrées et non d’une charge utile unique. Bloquer une chaîne littérale précise ne suffirait pas à combler la faille. La correction durable consiste à valider et à exécuter exactement le même chemin.
C’est ce que fait la version 1.19.2. D’après notre lecture du code source de la 1.19.2, Kyverno construit désormais une forme canonique unique du chemin, rejette les chemins qu’il ne peut pas canoniser, vérifie le namespace sur cette forme et envoie exactement cette forme au serveur d’API. Un problème voisin corrigé dans la même version, la CVE-2026-122310 (GHSA-3xfv-vq8x-qhg4), exploitait le même décalage entre la vérification sur la copie nettoyée et la requête brute en dissimulant des segments ../ derrière # ou ?. Il s’agit d’une CVE distincte, avec son propre enregistrement.
La chaîne d’élévation de privilèges, étape par étape
La personne à l’origine du signalement a démontré la chaîne sur Kubernetes 1.31, avec Kyverno 1.19.1 installé à partir du chart Helm standard et de ses valeurs par défaut.
- Créer une Policy de portée namespace. Le seul privilège du locataire est la création de
policies.kyverno.iodans son propre namespace. La politique contient unapiCalldont le chemin passe la restriction mais est acheminé ailleurs. - La déclencher. La création de n’importe quel objet ordinaire auquel la politique s’applique, par exemple une ConfigMap dans le namespace du locataire, amène Kyverno à évaluer la règle et à exécuter l’appel avec le ServiceAccount de son admission controller.
- Lire d’autres namespaces. La même technique permet de lire des objets dans d’autres namespaces, y compris des Secrets si le déploiement de Kyverno est autorisé à les lire.
- Écrire un webhook à l’échelle du cluster. Le ServiceAccount peut créer des MutatingWebhookConfigurations et des ValidatingWebhookConfigurations ; le locataire peut donc enregistrer son propre webhook, qui intercepte et réécrit ensuite les requêtes d’admission dans tous les namespaces.
- Obtenir les droits d’administrateur du cluster. L’avis décrit l’utilisation d’un tel webhook pour modifier les pods créés dans kube-system et, à partir de là, accorder au locataire les droits cluster-admin. Le résultat est une perte totale de confidentialité, d’intégrité et de disponibilité.
Aucune interaction utilisateur n’est nécessaire, et le webhook se déclenche lors de l’activité normale du cluster.
Qui est concerné
L’enregistrement CVE indique que Kyverno 1.19.1 est vulnérable et que la version 1.19.2 ne l’est pas. Les versions antérieures à 1.19.1 ne présentent pas ce contournement précis, car elles ne disposent d’aucune restriction de namespace. Elles sont en revanche touchées par les avis antérieurs que cette restriction devait corriger ; rester sur une version plus ancienne n’est donc pas une alternative sûre. Le risque est le plus élevé lorsque des propriétaires de namespaces, des pipelines CI ou des portails en libre-service sont autorisés à créer des Policies Kyverno.
Kyverno 1.19.2 a été publié le 20 octobre 2026, et ses notes de version recensent 24 avis de sécurité GitHub : 9 critiques, 14 élevés et 1 modéré. Plusieurs d’entre eux portent sur la validation des chemins d’API et le confinement aux namespaces. Le présent avis a été publié trois jours plus tard, le 23 octobre, mais l’avis comme l’enregistrement CVE désignent la version 1.19.2 comme version corrigée. Chaque avis possède son propre identifiant : faites la correspondance un par un plutôt que de traiter l’ensemble comme une seule CVE.
Ce qu’il faut vérifier dans vos propres clusters
Commencez par identifier la version de Kyverno réellement en cours d’exécution, et non celle qui figure dans votre dépôt Git :
kubectl get deployments -n kyverno -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.template.spec.containers[*].image}{"\n"}{end}'
Si un tag d’image est v1.19.1, planifiez dès maintenant le passage à la version 1.19.2. Vérifiez ensuite quatre points :
- Qui peut créer des Policies de portée namespace. Testez directement les identités des locataires et recherchez les rôles qui accordent
policies.kyverno.io, y compris les ClusterRoles agrégés qui ajoutent des droits aux rôles intégrés admin et edit. - Les politiques existantes qui utilisent apiCall. Listez-les et examinez chaque
urlPath, en particulier les chemins contenant%,..,?ou#. - Les configurations de webhooks. Comparez la liste avec ce que vous attendez. Kyverno crée ses propres webhooks : concentrez-vous sur les noms que vous ne reconnaissez pas et sur les dates de création récentes.
- Les journaux d’audit. Recherchez les requêtes du ServiceAccount de l’admission controller de Kyverno qui créent des configurations de webhooks ou lisent des Secrets en dehors de son schéma habituel.
kubectl auth can-i create policies.kyverno.io -n team-a --as=system:serviceaccount:team-a:default
kubectl get policies.kyverno.io -A -o json | jq -r '.items[] | select([.spec.rules[]?.context[]? | select(.apiCall)] | length > 0) | "\(.metadata.namespace)/\(.metadata.name)"'
kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations -o custom-columns=NAME:.metadata.name,CREATED:.metadata.creationTimestamp
Remplacez team-a par vos propres namespaces et identités de locataires. Si vous trouvez un webhook inexpliqué sur un cluster qui a exécuté la version 1.19.1, traitez-le comme un incident potentiel : conservez les journaux d’audit avant de supprimer quoi que ce soit.
La leçon plus générale : auditer celui qui applique les règles
Les admission controllers, les moteurs de politiques et les opérateurs sont souvent les composants les plus privilégiés d’un cluster. Ils ont besoin de droits étendus pour remplir leur rôle, et les locataires interagissent avec eux au quotidien. Cela en fait une cible attrayante. Ici, le modèle multi-locataire reposait sur une seule vérification, et une seule étape de décodage traitée différemment par la vérification et par la requête a suffi à le mettre en défaut.
Pour les plateformes Kubernetes de cloud privé et multi-locataires, trois pratiques sont utiles. Considérez les moteurs de politiques comme faisant partie de la surface d’attaque et suivez leurs versions de sécurité d’aussi près que la version de Kubernetes. N’accordez à leurs ServiceAccounts que les droits dont ils ont besoin, par exemple en n’autorisant pas la lecture des Secrets sauf si une politique l’exige. Enfin, examinez les fonctionnalités auxquelles les locataires ont accès par délégation, car une fonctionnalité qui s’exécute avec les privilèges de la plateforme transforme une entrée du locataire en action de la plateforme.
Sources
- Avis de sécurité Kyverno GHSA-39w8-hv5g-f73w : élévation aux droits cluster-admin via un contournement de la restriction de namespace d’apiCall de la v1.19.1 par une séquence d’échappement pourcent mal formée
- Enregistrement CVE : CVE-2026-124440
- Avis VulnCheck : Kyverno 1.19.1 : élévation de privilèges via un contournement de la restriction de namespace d’apiCall
- Correctif connexe dans la même version, CVE-2026-122310 : avis VulnCheck et GHSA-3xfv-vq8x-qhg4
- Notes de version de Kyverno v1.19.2 : github.com/kyverno/kyverno/releases/tag/v1.19.2
Global
Japan
Korea
China
Taiwan
Vietnam
Thailand
Indonesia
Portugal
Spain
Germany
Egypt
Russia