Security musings

Catégories

Tags

🔍 Licence d'Utilisation 🔍

Sauf mention contraire, le contenu de ce blog est sous licence CC BY-NC-ND 4.0.

© 2025 à 2042 Sébastien Gioria. Tous droits réservés.

⏱️
Temps de lecture estimé
~10 minutes

Cet article fait partie de la série OWASP Top 10 Kubernetes 2026. Retrouvez le tableau de bord complet des dix risques et la matrice STRIDE sur la page d’entrée de la série.


K06 commence par un point qui dérange : un Kubernetes Secret n’est pas un mécanisme de sécurité. C’est un objet de configuration qui sépare les données sensibles des manifests applicatifs, encodé en base64 pour faciliter la manipulation, pas pour protéger.

Le base64 se décode en une commande. Toute personne ayant accès à etcd, accès RBAC get sur les secrets, ou accès aux spécifications de pods peut lire les valeurs en clair. Ce n’est pas un bug de Kubernetes ; c’est une propriété documentée et délibérée de l’objet Secret. Le problème n’est pas le format, c’est ce qu’on en fait autour.

La distinction entre “le secret est dans une variable d’environnement” et “le secret est dans un volume monté” n’est pas anodine. Les variables d’environnement apparaissent dans les logs de crash, dans les dumps de process, dans certaines interfaces de monitoring. Un volume monté reste un fichier dans le conteneur ; plus discret, plus difficile à exposer accidentellement.

Vecteurs d’attaque

Le classique silencieux

NDLR : ON DIT CHIFFRER ET PAS CRYPTER !!!! Le débat étant posé, passons au sujet

Commencons par celui-là parce qu’il résume le problème : des équipes qui croient que les Secrets sont chiffrés parce qu’ils “ne sont pas en clair” dans le manifest. Le base64 n’est pas du chiffrement. C’est un encodage réversible sans clé.

Un accès RBAC get sur les secrets du namespace. C’est tout ce qu’il faut pour le lire…

Le vecteur plus sournois : les secrets qui apparaissent dans les sorties de kubectl describe pod, dans les logs des webhooks d’admission, dans les outils de monitoring qui capturent les variables d’environnement au démarrage. Le secret ne sort pas de Kubernetes ; il sort par un canal secondaire que personne n’a audité.

La bombe à retardement

Le scénario est si classique qu’il devrait être enseigné dès le premier cours sur Kubernetes (et de manière générale dans TOUS LES COURS sur la sécurité) : un manifest de Deployment commité avec les valeurs des secrets en dur, ou un fichier secret.yaml poussé par erreur dans un repo git.

git(et Internet non plus) n’oublie pas. Même si le fichier est supprimé dans le commit suivant, il reste dans l’historique. Les scanners de secrets comme TruffleHog, Gitleaks ou les checks automatiques de GitHub scannent justement cet historique.

NDLR : Plus c’est gros, plus ca passe ….

Le canal d’exfiltration accidentel

Injecter un secret via valueFrom.secretKeyRef dans une variable d’environnement est pratique. Le problème n’est pas le mécanisme ; c’est l’effet de bord : cette valeur se retrouve dans kubectl describe pod, dans les dumps mémoire, dans les rapports d’erreur, dans les traces APM si l’outil capture les variables d’environnement du processus.

La règle à appliquer pour limiter les fuites : les secrets sensibles (clés privées, tokens d’accès, credentials) se montent en volume, pas en variable d’environnement.

Les valeurs moins sensibles (noms d’hôtes, ports, noms de base de données) peuvent rester en variable. La distinction doit être documentée et appliquée en review.

Mitigations 2026

Chiffrement at-rest avec un KMS

C’est la mitigation fondamentale côté stockage. Sans chiffrement au repos, un accès direct à etcd ou à une sauvegarde etcd expose tous les secrets en base64 décodable. Avec un KMS, les données chiffrées dans etcd ne sont déchiffrables que via le HSM du provider ; un snapshot etcd volé ne suffit plus.

L’impact ne porte que sur le stockage à froid. Il ne protège pas contre un accès API avec les bons droits RBAC. C’est la couche de défense en profondeur côté stockage, pas le remplacement du RBAC.

External Secrets Operator pour déléguer au bon outil

Les secrets d’application ne devraient pas vivre dans etcd. En 2026, l’External Secrets Operator (ESO) et le Secrets Store CSI Driver sont les deux approches standard pour injecter des secrets depuis un Vault (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault) dans les pods Kubernetes.

Ca devrait être la norme :

  • les secrets restent dans un système secure (rotation automatique, audit log dédié, ACL fines)
  • les objets Secret Kubernetes deviennent éphémères et régénérés à chaque cycle plutôt que stockés en permanence dans etcd.

Si le contexte ne permet pas ce niveau de maturité immédiatement, le minimum est le chiffrement au repos via un KMS et un RBAC strict sur les secrets.

RBAC strict sur les secrets et scan git

Le droit get sur les secrets d’un namespace doit être réservé aux opérateurs qui en ont un besoin explicite et documenté. Les pipelines CI/CD ne devraient avoir accès qu’aux secrets dont ils ont besoin pour déployer. Le RBAC en détail dans K08.

Côté git : un scan TruffleHog/GitLeaks/… de l’historique complet des repos qui touchent à Kubernetes, puis un hook pre-commit ou une vérification CI qui bloque les commits contenant des patterns de secrets.

Ce n’est pas une protection parfaite, mais fermer le canal git enlève le plus gros. Rappel la CISA…

DevSecOps : intégrer K06 dans la chaîne CI/CD

Phase Outil Action K06
Code TruffleHog, Gitleaks, pre-commit Scanner l'historique git et bloquer les commits contenant des secrets ou kubeconfigs.
Build conftest, semgrep Refuser les manifests avec des secrets encodés en dur ou des variables d'environnement sensibles.
Deploy Kyverno + ESO Imposer l'usage de l'External Secrets Operator pour les namespaces production ; bloquer les Secret objects manuels.
Operate kube-bench, audit RBAC Vérifier le chiffrement etcd at-rest et auditer les droits get sur les secrets par namespace.
Monitor Falco, audit log API Alerter sur tout accès get ou list aux secrets de production hors workflow normal.
🔒 Plus d'éléments en contenu premium
Ce contenu représente de nombreuses heures de travail, d'expérience etc... J'ai remarqué que mon contenu était repris par certaines sociétés/personnes et j'ai donc décidé de donner du contenu minimal sur ce blog. C'est pourquoi je vous invite a me contacter sur LinkedIn en mentionnant cet article pour plus d'informations.

À retenir 📌
  • Un Secret Kubernetes n'est pas chiffré : le base64 est un encodage, pas une protection. L'activer ne donne aucune garantie de confidentialité.
  • Chiffrement at-rest KMS obligatoire : c'est la protection du stockage etcd ; sans ça, une snapshot suffit à tout lire.
  • External Secrets Operator est l'approche cible : les secrets vivent dans un coffre-fort externe, pas dans etcd.
  • git n'oublie pas : scanner l'historique des repos avec TruffleHog avant de considérer le sujet réglé.
  • Préférer les volumes aux variables d'environnement pour les secrets sensibles ; ils sont moins exposés aux canaux secondaires (logs, APM, crash dumps).