10 bonnes pratiques de sécurité Docker
8 janvier 2025
0 minutes de lecturePrincipaux aspects de la sécurité Docker
La sécurité Docker concerne la création, l’exécution et l’orchestration des conteneurs Docker. Elle couvre la sécurité des Dockerfiles et des images de base Docker, ainsi que les aspects liés à la sécurité des conteneurs Docker à l’exécution — notamment les privilèges utilisateur, le daemon Docker, la gestion adéquate des ressources processeur d’un conteneur et d’autres enjeux liés à l’orchestration des conteneurs Docker à grande échelle.
La sécurité des conteneurs Docker soulève 4 grands problèmes de sécurité :
Sécurité des Dockerfiles et bonnes pratiques
Sécurité des conteneurs Docker à l’exécution
Risques de sécurité de la chaîne d’approvisionnement liés à Docker Hub et conséquences sur les images de conteneurs Docker
Aspects de sécurité de l’orchestration de conteneurs cloud native liés à Kubernetes et Helm

La sécurité des conteneurs pour le DevSecOps
Détectez et corrigez gratuitement les vulnérabilités des conteneurs avec Snyk.
10 bonnes pratiques de sécurité Docker
1. Privilégiez des images de base minimales
Un problème courant de sécurité des conteneurs Docker est de se retrouver avec des images volumineuses. En règle générale, plus un conteneur contient de logiciels, plus sa surface d’attaque potentielle est importante. Le principe consiste donc à n’inclure que le strict minimum nécessaire au fonctionnement de votre application. La solution la plus simple consiste souvent à utiliser une image de conteneur Docker générique pour démarrer rapidement. Il peut s’agir d’une image de système d’exploitation comme Debian ou d’une image d’exécution officielle, telle que Node. Si votre projet n’a pas besoin de bibliothèques ni d’utilitaires système génériques, mieux vaut éviter d’utiliser un système d’exploitation complet comme image de base.
Par nature, les images d’environnement d’exécution génériques contiennent tout ce qu’il faut pour exécuter des applications dans la plupart des cas, et probablement une grande quantité de logiciels inutilisés par votre application. La bonne pratique consiste à tirer parti des builds multi-étapes : vous pouvez utiliser une image générique pendant la compilation, qui contient les outils nécessaires, puis transférer l’application compilée dans une image légère, avec un environnement minimal adapté à la production.
Vous pouvez aussi envisager des distributions spécialisées pour les conteneurs, comme les images distroless de Google ou Alpine Linux, beaucoup plus légère par défaut. Pour les langages compilés comme Go ou C, vous pouvez même créer des conteneurs complètement vides en indiquant scratch dans le Dockerfile, car ces types de binaires peuvent ne dépendre d’aucun élément externe.
2. Utilisez un utilisateur aux privilèges minimaux
Si un Dockerfile ne précise pas de USER, le conteneur est exécuté par défaut avec l’utilisateur root. En pratique, il existe très peu de raisons pour lesquelles un conteneur devrait disposer des privilèges root, et cela peut facilement devenir un problème de sécurité Docker. Par défaut, Docker exécute les conteneurs avec l’utilisateur root. Lorsque cet espace de noms est ensuite associé à l’utilisateur root du conteneur en cours d’exécution, le conteneur peut potentiellement accéder aux privilèges root sur l’hôte Docker. L’exécution d’une application dans le conteneur avec l’utilisateur root facilite l’escalade des privilèges si l’application elle-même présente une vulnérabilité exploitable.
Pour limiter les risques, créez un utilisateur et un groupe dédiés à l’application dans l’image Docker. Utilisez la directive USER dans le Dockerfile pour que le conteneur exécute l’application avec les privilèges les plus faibles possible.
N’oubliez pas que les nouveaux utilisateurs ou groupes peuvent ne pas exister dans l’image. Veillez à les créer à l’aide des instructions du Dockerfile.
Voici un exemple complet pour une image Ubuntu générique :
L’exemple ci-dessus :
crée un utilisateur système (-r) sans mot de passe, sans répertoire personnel ni shell
ajoute l’utilisateur créé à un groupe existant que nous avons créé au préalable (avec groupadd)
ajoute un dernier argument correspondant au nom de l’utilisateur à créer et à associer au groupe créé
Si vous appréciez Node.js et les images Alpine, celles-ci incluent déjà un utilisateur générique nommé node. Voici un exemple Node.js qui utilise cet utilisateur générique node :
Si vous développez des applications Node.js, consultez les bonnes pratiques officielles Docker et Node.js.
La sécurité des conteneurs pour le DevSecOps
Détectez et corrigez gratuitement les vulnérabilités des conteneurs avec Snyk.
3. Signez et vérifiez les images pour contrer les attaques de type MITM
L’authenticité des images Docker est un enjeu important. Nous leur faisons largement confiance, puisque nous les utilisons littéralement comme conteneurs pour exécuter notre code en production. Il est donc essentiel de vérifier que l’image récupérée est bien celle publiée par son éditeur et qu’aucun tiers ne l’a modifiée. Une altération peut se produire lors du transfert entre le client Docker et le registre, ou à la suite de la compromission du compte du propriétaire du registre pour y publier une image malveillante.
La signature des images et des artefacts associés est un élément clé de la sécurisation de votre chaîne d’approvisionnement logicielle, et les technologies dans ce domaine évoluent rapidement. À l’heure actuelle, les deux outils les plus couramment utilisés sont :
Docker Notary v1, à la base de la fonctionnalité Docker Content Trust (DCT) intégrée à l’interface CLI Docker
Le projet SigStore, notamment son outil cosign, permet de signer, stocker et vérifier facilement des artefacts.
Docker Content Trust
Docker Content Trust (DCT) existe depuis plusieurs années et permet aux auteurs d’images de signer les balises qu’ils publient sur les serveurs de registre d’images compatibles avec l’API Docker Notary, comme DockerHub. Une fois DCT activé sur votre hôte Docker, toute image dont la signature ne peut pas être vérifiée est bloquée et ne peut pas être récupérée, publiée ou exécutée.
La signature de votre image de conteneur avec DCT est simple : définissez la variable d’environnement `DOCKER_CONTENT_TRUST=1`. Lorsque vous publiez votre image sur DockerHub ou tout autre registre d’images compatible avec Notary, Docker se charge d’appliquer la signature et de l’enregistrer avec la balise de l’image
Au démarrage du conteneur, il suffit de définir la même variable d’environnement pour appliquer la vérification des signatures. L’interface CLI Docker refusera alors de récupérer ou de démarrer une image de conteneur dont la balise n’est pas signée ou dont la signature est invalide.
Les opérations plus complexes, comme la révocation de clés, sont gérées avec l’outil binaire notary. Pour en savoir plus sur Notary v1 et DCT, consultez la documentation officielle.
Sigstore
Les outils du projet Sigstore visent à gérer non seulement les signatures d’images de conteneurs, mais aussi celles de tout artefact que vous souhaitez signer : nomenclature logicielle (SBOM), attestations concernant un artefact (par exemple, des métadonnées de build), ou même un fichier binaire non-image, aussi appelé « blob ».
Dans le cas le plus simple, la signature d’une image consiste à exécuter le binaire `cosign sign` en indiquant le registre et l’image:balise à signer. La commande `cosign verify` correspondante permet de valider la signature.
Depuis la version v1.9, cosign exige que vous génériez et gériez vous-même vos paires de clés. Bien qu’un outil `generate-key-pair` très facile à utiliser soit également proposé (voir ci-dessus), la prochaine version GA prendra en charge une fonction de signature « sans clé ». Celle-ci repose sur un mécanisme d’autorisation OpenID Connect (OIDC) qui génère automatiquement des paires de clés éphémères comportant votre adresse e-mail. Cette fonctionnalité est disponible dès maintenant : définissez `COSIGN_EXPERIMENTAL=1` avant d’exécuter les commandes `sign` ou `verify`.
Il faut également réfléchir à la manière dont vous exécuterez les conteneurs signés. Pour la plupart d’entre nous, Kubernetes est la plateforme de prédilection, mais il ne prend pas en charge DCT nativement. À moins d’utiliser une distribution spécifique qui l’implémente, vous devrez donc mettre en place une forme de contrôle à l’exécution. Heureusement, l’API Kubernetes d’admission des contrôleurs peut être utilisée à cette fin, et des projets open source comme Connaisseur peuvent gérer les signatures DCT / Notary v1 ainsi que Cosign.
4. DÉTECTEZ, CORRIGEZ ET SURVEILLEZ LES VULNÉRABILITÉS OPEN SOURCE
Lorsque nous choisissons une image de base pour notre conteneur Docker, nous héritons indirectement de tous les problèmes de sécurité des conteneurs qu’elle comporte. Il peut s’agir de paramètres par défaut mal configurés qui nuisent à la sécurité du système d’exploitation, ou encore des bibliothèques système incluses dans l’image de base choisie.
Un bon premier réflexe consiste à utiliser l’image de base la plus légère possible, tout en veillant à ce que votre application fonctionne sans problème. Vous réduisez ainsi la surface d’attaque en limitant l’exposition aux vulnérabilités. En revanche, cette approche n’effectue aucun audit à elle seule et ne vous protège pas des vulnérabilités qui pourraient être révélées ultérieurement pour la version de l’image de base utilisée.
Pour vous protéger des vulnérabilités des logiciels open source, vous pouvez utiliser des outils comme Snyk afin d’assurer une analyse continue de la sécurité Docker et de surveiller les vulnérabilités présentes dans toutes les couches des images Docker utilisées.

Analysez une image Docker à la recherche de vulnérabilités connues avec ces commandes :
Surveillez une image Docker pour être averti par Snyk des vulnérabilités nouvellement découvertes dans l’image et recevoir des conseils de correction :
D’après les analyses effectuées par les utilisateurs de Snyk, nous avons constaté que 44 % des images Docker analysées présentaient des vulnérabilités connues, alors qu’il existait des images de base plus récentes et plus sécurisées. Snyk fournit des conseils de correction uniques qui permettent aux développeurs de prendre les mesures nécessaires et de mettre à niveau leurs images Docker.
Snyk a également constaté que pour 20 % de l’ensemble des images Docker analysées, il suffisait de reconstruire l’image Docker pour réduire le nombre de vulnérabilités.
Comment auditer la sécurité des conteneurs ?
L’analyse de votre projet de conteneur Linux à la recherche de vulnérabilités connues est essentielle pour assurer la sécurité de votre environnement. Pour cela, Snyk analyse l’image de base, le système d’exploitation (OS), les paquets installés et gérés par le gestionnaire de paquets, ainsi que les binaires clés des couches qui n’ont pas été installés par l’intermédiaire du gestionnaire de paquets.
L’outil de gestion des vulnérabilités des conteneurs de Snyk fournit des conseils et des recommandations de correction pour les images publiques de Docker Hub, notamment en indiquant l’image de base recommandée, la couche du Dockerfile où une vulnérabilité a été détectée, et bien plus encore.
5. NE DIVULGUEZ PAS D’INFORMATIONS SENSIBLES DANS LES IMAGES DOCKER
Lors de la création d’une application dans une image Docker, vous avez parfois besoin de secrets, comme une clé privée SSH pour récupérer du code depuis un dépôt privé, ou de jetons pour installer des paquets privés. Si vous les copiez dans le conteneur intermédiaire Docker, ils sont mis en cache dans la couche où ils ont été ajoutés, même si vous les supprimez par la suite. Ces jetons et ces clés doivent rester en dehors du Dockerfile.
Utilisez des builds multi-étapes
Pour améliorer la sécurité des conteneurs Docker, vous pouvez également utiliser des builds multi-étapes. Profitez de la prise en charge de cette fonctionnalité par Docker pour récupérer et gérer les secrets dans une couche d’image intermédiaire, qui sera ensuite supprimée afin qu’aucune donnée sensible ne se retrouve dans l’image finale. Utilisez du code pour ajouter les secrets à cette couche intermédiaire, comme dans l’exemple suivant :
Utilisez les secrets Docker BuildKit
Utilisez une fonctionnalité de Docker BuildKit pour gérer les secrets et monter des fichiers sensibles sans les mettre en cache, comme dans l’exemple suivant :
En savoir plus sur les secrets de build Docker sur leur site.
Attention aux copies récursives
Soyez également vigilant lorsque vous copiez des fichiers dans l’image en cours de création. Par exemple, la commande suivante copie récursivement l’intégralité du dossier du contexte de build dans l’image Docker. Elle pourrait donc aussi y copier des fichiers sensibles :
Si votre dossier contient des fichiers sensibles, supprimez-les ou utilisez .dockerignore pour les ignorer :
Comment protéger un conteneur Docker ?
Veillez à utiliser des builds multi-étapes pour que l’image de conteneur créée pour la production ne contienne ni ressources de développement, ni secrets ou jetons.
Veillez également à utiliser un outil de sécurité des conteneurs pour analyser vos images Docker depuis l’interface CLI, directement depuis Docker Hub ou parmi celles déployées en production avec Amazon ECR, Google GCR ou d’autres services.
6. Utilisez des tags fixes pour garantir l’immutabilité
Chaque image Docker peut avoir plusieurs tags, qui correspondent à différentes variantes d’une même image. Le tag le plus courant est latest, qui désigne la version la plus récente de l’image. Les tags d’image ne sont pas immuables : l’auteur de l’image peut publier plusieurs fois le même tag.
Cela signifie que l’image de base de votre fichier Docker peut changer d’un build à l’autre. Les modifications apportées à l’image de base peuvent alors entraîner un comportement incohérent. Voici plusieurs façons d’atténuer ce problème et d’améliorer la sécurité de votre environnement Docker :
Privilégiez le tag le plus précis disponible. Si l’image possède plusieurs tags, par exemple :8 et :8.0.1, voire :8.0.1-alpine, choisissez le dernier, car il désigne l’image de façon plus précise. Évitez les tags trop génériques, comme latest. Gardez à l’esprit qu’un tag précis peut finir par être supprimé.
Pour éviter qu’un tag d’image spécifique devienne indisponible et bloque les équipes qui en dépendent, vous pouvez héberger une copie locale de cette image dans un registre ou un compte que vous contrôlez. Tenez compte de la charge de maintenance associée à cette approche, car vous devrez gérer un registre. Copier l’image que vous souhaitez utiliser dans votre propre registre est une bonne pratique pour vous assurer qu’elle ne change pas.
Soyez très précis ! Au lieu de récupérer une image à l’aide d’un tag, utilisez sa référence SHA256, qui garantit que chaque récupération renvoie la même image. Attention toutefois : l’utilisation d’une référence SHA256 peut comporter des risques. Si l’image change, son empreinte peut ne plus exister.
Les images Docker sont-elles sécurisées ?
Les images Docker peuvent reposer sur des distributions Linux open source et intégrer des logiciels et des bibliothèques open source. Une récente étude de Snyk sur l’état de la sécurité open source a révélé que les images Docker les plus populaires contiennent au moins 30 vulnérabilités.
7. Utilisez COPY plutôt que ADD
Lors de la création d’une image Docker, Docker propose deux commandes pour copier des fichiers de l’hôte vers l’image : COPY et ADD. Ces instructions sont similaires, mais leurs fonctionnalités diffèrent et peuvent avoir des conséquences sur la sécurité du conteneur Docker :
COPY — copie les fichiers locaux de manière récursive en indiquant explicitement les fichiers ou répertoires source et de destination. Avec COPY, vous devez préciser les chemins.
ADD — copie les fichiers locaux de manière récursive, crée implicitement le répertoire de destination s’il n’existe pas et accepte des archives comme sources locales ou des URL distantes, qu’il extrait ou télécharge dans le répertoire de destination.
Les différences entre ADD et COPY peuvent sembler subtiles, mais elles sont importantes. Tenez-en compte pour éviter d’éventuels problèmes de sécurité :
Le téléchargement de données depuis des URL distantes directement vers un emplacement source peut exposer à des attaques de l’homme du milieu, qui modifient le contenu du fichier téléchargé. Il faut également vérifier davantage la provenance et l’authenticité des URL distantes. Lorsque vous utilisez COPY, les fichiers récupérés depuis des URL distantes doivent être téléchargés via une connexion TLS sécurisée et leur provenance doit aussi être vérifiée.
Espace et couches de l’image : COPY permet d’ajouter une archive provenant d’un emplacement distant et de la décompresser dans des couches distinctes, ce qui optimise le cache de l’image. Si vous avez besoin de fichiers distants, regroupez leur téléchargement, leur extraction et leur nettoyage dans une seule commande RUN. Vous n’aurez ainsi qu’une seule couche, au lieu de plusieurs avec ADD.
Avec des archives locales, ADD les extrait automatiquement dans le répertoire de destination. Cela peut être acceptable, mais comporte un risque de bombes ZIP et de vulnérabilités Zip Slip, qui pourraient alors être déclenchées automatiquement.
8. Utilisez des étiquettes de métadonnées
Les étiquettes d’image fournissent des métadonnées sur l’image que vous créez. Elles aident les utilisateurs à comprendre facilement comment l’utiliser. L’étiquette la plus courante est « maintainer », qui indique l’adresse e-mail et le nom de la personne chargée de la maintenance de l’image. Ajoutez des métadonnées à l’aide de la commande LABEL suivante :
En plus d’un contact de maintenance, ajoutez toutes les métadonnées qui vous semblent utiles. Il peut s’agir d’un hachage de commit, d’un lien vers le build correspondant, de l’état de qualité (tous les tests ont-ils réussi ?), du code source, de l’emplacement de votre fichier SECURITY.TXT, etc.
Lorsque vous ajoutez des étiquettes, il est recommandé d’inclure un fichier SECURITY.TXT (RFC5785) qui renvoie à votre politique de divulgation responsable pour le schéma d’étiquetage Docker, comme dans l’exemple suivant :
En savoir plus sur les étiquettes des images Docker.
9. Utilisez un build multi-étapes pour créer des images Docker légères et sécurisées
Lors de la création de votre application avec un Dockerfile, de nombreux artefacts ne sont nécessaires que pendant le build. Il peut s’agir d’outils et de bibliothèques de développement pour la compilation, de dépendances nécessaires à l’exécution des tests unitaires, de fichiers temporaires, de secrets, etc.
Conserver ces artefacts dans l’image de base, susceptible d’être utilisée en production, augmente la taille de l’image Docker. Le téléchargement prend alors plus de temps et la surface d’attaque s’élargit, car davantage de paquets sont installés. Il en va de même pour l’image Docker utilisée : vous aurez peut-être besoin d’une image spécifique pour le build, mais pas pour exécuter le code de l’application.
Golang en est un bon exemple. Pour créer une application Golang, vous avez besoin du compilateur Go. Celui-ci génère un exécutable qui fonctionne sur n’importe quel système d’exploitation, sans dépendances, y compris dans une image scratch.
C’est une bonne raison pour laquelle Docker propose la fonctionnalité de build multi-étapes. Elle vous permet d’utiliser plusieurs images temporaires pendant le processus de build, tout en ne conservant que la dernière image et les éléments que vous y avez copiés. Vous obtenez ainsi deux images :
Première image : une image très volumineuse, contenant de nombreuses dépendances utilisées pour créer votre application et exécuter les tests.
Deuxième image : une image très légère, avec peu de bibliothèques, qui ne contient qu’une copie des artefacts nécessaires à l’exécution de l’application en production.
10. Utilisez un linter
Adoptez un linter pour éviter les erreurs courantes et définir des bonnes pratiques que les ingénieurs peuvent appliquer automatiquement. C’est un outil utile pour analyser statiquement les problèmes de sécurité des Dockerfiles.
hadolint est l’un de ces linters. Il analyse un Dockerfile et affiche un avertissement pour chaque erreur qui ne respecte pas ses règles de bonnes pratiques.

Hadolint est encore plus efficace lorsqu’il est utilisé dans un environnement de développement intégré (IDE). Par exemple, avec hadolint en extension pour VSCode, les erreurs de linting s’affichent pendant la saisie. Vous pouvez ainsi écrire de meilleurs Dockerfiles plus rapidement.
La sécurité des conteneurs pour le DevSecOps
Détectez et corrigez gratuitement les vulnérabilités des conteneurs avec Snyk.
Comment renforcer la sécurité d’une image de conteneur Docker ?
Vous pouvez utiliser des linters comme hadolint ou dockle pour vérifier que votre Dockerfile est configuré de manière sécurisée. Pensez également à analyser vos images de conteneurs pour éviter que des vulnérabilités ayant un impact grave sur la sécurité ne se retrouvent dans vos conteneurs de production.
Docker présente-t-il un risque pour la sécurité ?
Docker est une technologie de virtualisation logicielle qui a gagné en popularité et s’est largement répandue. Lorsque nous créons et déployons des conteneurs Docker, nous devons appliquer les bonnes pratiques de sécurité afin d’atténuer des risques tels que les vulnérabilités intégrées aux images Docker de base ou les violations de données dues à une mauvaise configuration des conteneurs.
Comment sécuriser un conteneur Docker ?
Suivez les bonnes pratiques de sécurité Docker : utilisez des images Docker de base qui présentent peu ou pas de vulnérabilités connues, appliquez des paramètres de sécurité à vos Dockerfiles et surveillez vos conteneurs déployés pour détecter toute dérive de l’image entre le développement et la production. Veillez également à respecter les bonnes pratiques d’Infrastructure as Code pour les solutions d’orchestration de conteneurs.
Sécurité Docker : ressources supplémentaires
Pour conclure, si vous souhaitez suivre les bonnes pratiques de sécurité pour créer des images Docker optimisées pour les applications Node.js et Java :
Vous développez en Java ? Cette ressource devrait vous intéresser : Docker pour les développeurs Java : 5 points essentiels pour garantir votre sécurité
10 bonnes pratiques pour créer un conteneur Java avec Docker : une excellente fiche pratique détaillée pour créer des conteneurs de qualité production pour les applications Java.
10 bonnes pratiques pour conteneuriser des applications web Node.js avec Docker : si vous développez en Node.js, vous allez adorer ce guide pas à pas, qui explique comment créer des images Docker de base performantes et sécurisées pour vos applications Node.js.
Découvrez l’état de la sécurité des logiciels open source
Découvrez les tendances et les approches actuelles en matière de logiciels open source et de sécurité de la chaîne d’approvisionnement.



