← Docker — livraison et exploitation des applications

Module 7 / 8 · 90 min

Privilèges, secrets et limites du runtime

Réduire les possibilités après une compromission du processus.

Votre progression apparaîtra ici lorsque JavaScript est actif.

La progression et le meilleur score sont enregistrés uniquement dans ce navigateur. Aucun compte n’est nécessaire ; effacer les données du navigateur les supprime. Les durées de modules sont indicatives et incluent les exercices.

Comprendre le mécanisme

L’isolation repose notamment sur namespaces, cgroups et politiques de sécurité. Un utilisateur non root, des capacités minimales et des montages limités réduisent le périmètre accessible. L’accès au socket Docker peut permettre un contrôle très étendu de l’hôte selon la configuration ; ne le donnez pas à une application ordinaire par commodité. Le mode privilégié doit être justifié par un besoin précis, pas utilisé comme remède général aux erreurs de permission.

Raisonner et vérifier

Une racine en lecture seule exige de prévoir explicitement les répertoires temporaires ou données nécessaires. Les limites mémoire et CPU bornent certaines consommations, sans corriger une fuite mémoire ou un algorithme incorrect. Un conteneur n’est pas une preuve d’isolation absolue : maintenez aussi noyau, runtime et dépendances. Testez les droits nécessaires et les refus attendus sous le véritable utilisateur runtime.

Réduire les privilèges du processus

Exécuter le service avec un utilisateur non root peut limiter certaines opérations si le reste de la configuration respecte cette intention. Cela n’empêche pas toutes les vulnérabilités applicatives : le processus peut encore accéder aux données légitimement disponibles pour son rôle. Définissez les capacités nécessaires puis testez une opération refusée et un parcours nominal. Le durcissement doit réduire l’impact sans être confondu avec une preuve générale d’absence de bug.

Erreur fréquente à comprendre

Non root rend impossible toute vulnérabilité applicative.

Le contrôle ne remplace pas les autres défenses.

Ne garder que les capacités utiles

Les capabilities et autres options de privilège doivent correspondre à un besoin réel du service. En ajouter toutes élargit les pouvoirs disponibles, même si une fonction nominale semble continuer à marcher. Inventoriez les opérations système attendues et retirez les capacités superflues selon une procédure vérifiée. Une configuration minimale doit être testée, pas simplement copiée d’un autre produit dont les dépendances diffèrent.

Erreur fréquente à comprendre

Ajouter toutes les capabilities améliore l’isolation.

L’élargissement augmente les pouvoirs disponibles.

Définir les écritures nécessaires

Une racine de conteneur en lecture seule peut limiter des modifications inattendues, mais le programme a parfois besoin d’espaces temporaires ou de données explicitement montées. Identifiez-les et contrôlez leur durée et taille. Cette restriction ne chiffre pas les fichiers et ne filtre pas toutes les sorties réseau. Les tests doivent distinguer écriture interdite, écriture utile et chemin de reprise après une erreur de stockage.

Erreur fréquente à comprendre

Read-only interdit toutes les sorties réseau.

Les surfaces de fichier et réseau sont distinctes.

Le socket donne une capacité, pas un fichier anodin

Monter le socket Docker peut exposer des opérations puissantes sur le démon et l’environnement hôte selon les droits et la configuration. Ce n’est pas une lecture ordinaire comparable à une image publique. Évitez ce montage pour une application qui n’a pas besoin de ce contrôle. Une revue doit considérer l’impact d’une RCE dans le service qui pourrait alors utiliser l’interface exposée.

Erreur fréquente à comprendre

Monter le socket est une lecture ordinaire sans risque de contrôle.

L’API peut permettre des opérations puissantes sur l’hôte.

Distribuer les secrets selon leur usage

Un processus qui consomme un secret doit pouvoir l’obtenir d’une manière utile ; son injection ne le rend donc pas inaccessible à tout code exécuté dans ce périmètre. Limitez les détenteurs, les logs et la conservation. Séparez environnements et finalités pour réduire l’impact d’un incident. Une valeur publique de démonstration ne doit pas devenir le credential réel parce que le format d’injection paraît sécurisé.

Erreur fréquente à comprendre

Tout secret injecté devient impossible à extraire par le processus.

Le consommateur dispose nécessairement d’une capacité de lecture utile.

Borner sans prétendre réparer

Des limites de CPU et de mémoire participent au partage de ressources et peuvent borner certaines conséquences d’un abus ou d’une fuite. Elles ne corrigent pas automatiquement la cause. Une limite mémoire peut conduire à un arrêt, qui demande une stratégie de diagnostic et de reprise. Mesurez aussi files, volume de travail et délais ; déplacer l’attente vers une autre ressource ne fournit pas une capacité infinie.

Erreur fréquente à comprendre

Un conteneur possède une capacité infinie par isolation.

Les ressources physiques restent finies.

Comprendre le mode privilégié

Le mode privilégié élargit des possibilités au lieu de représenter une restriction maximale. Son utilisation doit donc être liée à un besoin explicite et à une analyse du périmètre. Un exemple qui fonctionne uniquement avec ce mode peut cacher un défaut de permissions ou une dépendance excessive. Cherchez la capacité minimale nécessaire et testez-la séparément, plutôt que rendre tout l’environnement accessible par facilité.

Erreur fréquente à comprendre

Privileged constitue la restriction maximale du runtime.

Ce mode donne davantage d’accès.

Maintenir le contenu exécuté

Une image identifiée par digest peut rester vulnérable ou devenir concernée par une information de sécurité nouvelle. La traçabilité facilite le repérage des instances affectées ; elle ne retire pas le besoin de maintenance. Définissez construction, analyse et mise à jour avec des vérifications de comportement. Le nom d’une base réputée ou le résultat ancien d’un scan ne garantit pas tout état futur.

Erreur fréquente à comprendre

Un digest fixé ne nécessite jamais une revue de vulnérabilités.

L’immuabilité n’efface pas les défauts découverts.

Garder l’autorisation dans le domaine

Un runtime durci limite des capacités système, pas les droits d’un utilisateur sur une facture. Une requête paramétrée et un compte non root peuvent encore renvoyer les données du mauvais tenant si le filtre métier est absent. Testez cette frontière directement avec deux acteurs. La défense doit combiner des propriétés complémentaires, sans attribuer à un mécanisme d’isolation la connaissance de toutes les règles du produit.

Erreur fréquente à comprendre

Un runtime durci autorise tout accès aux données.

Le confinement ne définit pas la politique d’objet.

Observer la restriction effective

Le fichier de déploiement peut être surchargé ou interprété dans un contexte différent de celui du poste. Vérifiez l’utilisateur, les montages, capacités et limites de l’instance réellement exécutée. Une intention dans un commentaire ne prouve rien de ces décisions. La preuve doit conserver la version et les observations utiles sans exposer les secrets, afin qu’un autre opérateur puisse comprendre ce qui a été testé.

Erreur fréquente à comprendre

Un commentaire non-root suffit à prouver l’utilisateur actif.

Le runtime peut être configuré autrement.

Atelier guidé : lire, expliquer et vérifier le code

services:
  api:
    image: example/lab-api:1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Le volume de l’atelier ne monte pas seulement des données métier : il expose le socket de l’environnement Docker. Un processus compromis pourrait disposer de capacités de contrôle importantes par cette interface selon sa configuration. Aucun port 443 ni mécanisme de chiffrement du volume n’est défini dans cet extrait ; ces réponses décriraient d’autres propriétés.

Réalisez la revue sur une configuration de laboratoire et demandez si le service a réellement besoin d’opérer le démon. Retirez le montage lorsqu’il ne correspond pas à sa responsabilité, puis vérifiez le parcours nominal. Complétez avec utilisateur, capacités et ressources minimales. Le but est de limiter l’impact d’un code hostile tout en conservant les contrôles métier qui empêchent un utilisateur ordinaire d’accéder aux données d’un autre.

Après une RCE : réduire les capacités du processus

Une défense en profondeur suppose que la prévention puisse échouer. Un processus compromis dispose au minimum des droits de l’application ; l’objectif est de limiter les capacités supplémentaires accessibles depuis ce point.

Exécutez sans root, retirez les capacités inutiles, évitez mode privilégié et socket Docker, et rendez le système de fichiers en lecture seule lorsque possible. Fournissez seulement les répertoires temporaires nécessaires avec budgets de taille et durée. Limitez aussi sorties réseau et accès aux secrets selon les besoins réels du service.

Ces mesures ne rendent pas le conteneur invulnérable et ne retirent pas les données que l’application doit légitimement lire. Vérifiez le fonctionnement nominal sous ces restrictions puis simulez des opérations de laboratoire qui doivent échouer, comme une écriture hors répertoire admis. Une configuration déclarative doit être confrontée aux permissions et montages réellement présents sur le runtime déployé.

Points de vigilance : La réduction des droits et des accès hôte diminue les possibilités après RCE ; ce n’est pas une isolation absolue. Une image petite ne neutralise pas les privilèges du processus. L’accès au socket peut permettre de contrôler le démon et compromettre l’hôte selon sa configuration. Le mode privilégié et les montages sensibles compromettent le confinement attendu.

Documentation de référence ↗

Exemple commenté

docker run --rm --read-only --tmpfs /tmp \
  --cap-drop ALL --user 10001:10001 \
  alpine:3.22 sh -c 'id; printf "lab" > /tmp/check'

Le processus utilise un identifiant limité, une racine en lecture seule et un espace temporaire explicite. L’application réelle doit être testée avec ses besoins spécifiques.

Exercice de mise en pratique

Inventoriez les chemins d’écriture et capacités dont votre service a réellement besoin.

Voir une proposition de correction

Lancez-le avec des privilèges réduits, observez les refus puis autorisez seulement les besoins démontrés. Vérifiez qu’un accès au socket Docker n’est pas présent.

Points de vérification

  • Limiter accès hôte et capacités.
  • Prévoir les zones d’écriture utiles.
  • Tester le compte runtime réel.

Contrôle de connaissances

Cours associé : Privilèges, secrets et limites du runtime ↗
Pourquoi éviter de monter le socket Docker dans une application ordinaire ?

Documentation de référence ↗

Validation du module

101 questions, objectif pédagogique de 75 %. Durée conseillée de 150 minutes, sans limite imposée. Les questions et les choix sont mélangés ; le corrigé apparaît après validation. Le contrôle rapide de la leçon et l’examen final du cours restent des exercices distincts.

Commencer ou reprendre les 101 questions →