Le danger dans votre Dockerfile : comment un seul COPY peut compromettre votre container

Dans le paysage en rapide évolution de la containerisation, Docker est devenu la norme de facto pour le déploiement d’applications. Cependant, avec l’augmentation des préoccupations de sécurité, l’utilisation accrue de Docker révèle des vulnérabilités telles que des failles dans les images de base, des attaques lors de l’exécution et des mauvaises configurations. Alors que la plupart des développeurs se concentrent sur la sécurité en runtime et les configurations réseau, les vulnérabilités les plus critiques se cachent souvent en plain sight dans le Dockerfile lui-même — où une instruction COPY mal placée peut ouvrir la porte à des brèches de sécurité catastrophiques.
Les avis de sécurité récents soulignent l’urgence de traiter les Dockerfiles comme du code critique pour la sécurité. Un container malveillant tournant sur Docker Desktop pourrait accéder au Docker Engine et lancer des containers supplémentaires sans que le socket Docker soit monté. Cela pourrait permettre un accès non autorisé aux fichiers utilisateur sur le système hôte, comme le démontre CVE-2025-9074. Cette révélation met en lumière comment les hypothèses fondamentales de la containerisation sur l’isolation peuvent s’effondrer lorsque les pratiques de sécurité de base sont négligées.
Les vulnérabilités cachées dans votre Dockerfile
La nature trompeuse des couches de container
Chaque instruction dans un Dockerfile crée une nouvelle couche dans l’image résultante. Cette architecture en couches, tout en étant efficace pour le cache et la distribution, crée une piste d’audit persistante de chaque action effectuée lors de la build. Même si un fichier est supprimé dans une instruction ultérieure du Dockerfile, il peut encore être accessible dans les couches intermédiaires, rendant secrets et données sensibles définitivement intégrés dans l’historique de l’image.
Considérons cet extrait de Dockerfile apparemment innocent :
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY .env ./
RUN chmod +x deploy.sh && ./deploy.sh
RUN rm .env
COPY . .
CMD ["npm", "start"]
Malgré l’instruction RUN rm .env, le fichier d’environnement reste accessible dans la couche créée par COPY .env ./. Les attaquants peuvent extraire cette couche à l’aide de commandes Docker simples ou d’outils d’analyse d’images, récupérant ainsi des identifiants que les développeurs pensaient avoir supprimés en toute sécurité.
La contamination par build multi-étapes
Les builds multi-étapes représentent l’une des fonctionnalités les plus puissantes de Docker pour créer des images légères et sécurisées. Divisez vos instructions Dockerfile en étapes distinctes pour vous assurer que la sortie ne contient que les fichiers nécessaires à l’exécution de l’application. Cependant, mal implémentés, ils peuvent devenir des vecteurs d’attaques sophistiquées de la chaîne d’approvisionnement.
L’instruction COPY --from conçue pour copier des artefacts entre les étapes de build peut involontairement introduire du contenu compromis lorsqu’elle référence des images externes ou des étapes construites avec des dépendances contaminées. Considérons cet exemple :
FROM node:18 as builder
RUN npm install -g suspicious-build-tool
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
Si le package suspicious-build-tool contient du code malveillant, il peut injecter des portes dérobées dans les artefacts de build, qui sont ensuite copiés dans l’étape de production. L’image finale semble propre et minimale, masquant la compromission survenue lors du build.
Le problème de confiance dans l’image de base
La fondation de chaque application containerisée repose sur l’image de base spécifiée dans l’instruction FROM. Pourtant, de nombreux développeurs considèrent le choix de l’image de base comme une décision technique mineure plutôt qu’un choix critique de sécurité. Les images publiques non vérifiées, même avec des millions de téléchargements, peuvent contenir des logiciels malveillants préinstallés, des portes dérobées ou des versions vulnérables.
Une analyse récente des images Docker Hub populaires révèle des statistiques alarmantes : plus de 30 % des images apparemment officielles contiennent au moins une vulnérabilité à haute gravité, et beaucoup incluent des packages inutiles augmentant la surface d’attaque. Lorsqu’ils utilisent des images de commodité comme python:latest sans comprendre leur composition, les développeurs héritent non seulement de la fonctionnalité prévue, mais aussi de potentielles vulnérabilités.
Vecteurs d’attaque avancés via les instructions COPY
Injection de secrets via le contexte de build
Les implications de sécurité de l’instruction COPY vont bien au-delà de la simple copie de fichiers sensibles. Le contexte de build — tout ce qui se trouve dans le répertoire où la commande docker build est exécutée — devient accessible au processus de build. Les développeurs incluent souvent involontairement des informations sensibles dans ce contexte par des structures de répertoires négligentes ou des règles .dockerignore trop larges.
Un vecteur d’attaque particulièrement insidieux implique l’utilisation d’arguments de build et de variables d’environnement dans les instructions COPY :
FROM ubuntu:20.04
ARG SECRET_KEY
COPY --chown=www-data:www-data config/${SECRET_KEY}.conf /etc/app/
Ce motif, tout en semblant utiliser les arguments de build de manière sécurisée, crée plusieurs vulnérabilités. La valeur SECRET_KEY devient définitivement intégrée dans les métadonnées de l’image, et le fichier de configuration référencé est copié en fonction d’une entrée externe pouvant être manipulée pour accéder à des fichiers non destinés.
Exploitation des liens symboliques et traversée de chemins
La gestion des liens symboliques lors des opérations COPY peut conduire à un accès non prévu aux fichiers. Lorsque le contexte de build contient des liens symboliques pointant en dehors de la structure de répertoire prévue, l’instruction COPY suit ces liens, exposant potentiellement des fichiers du système hôte au processus de build.
Les attaquants pouvant influencer le contexte de build (par exemple via des pipelines CI/CD compromis) peuvent créer des liens symboliques qui traversent le système de fichiers hôte :
ln -s /etc/passwd ./innocent-looking-file.txt
ln -s /home/user/.ssh/id_rsa ./public-key.txt
L’instruction Dockerfile COPY . /app/ résultante copierait sans le savoir ces fichiers sensibles du système hôte dans l’image, les rendant accessibles à toute personne ayant accès à l’image.
Le paradoxe de sécurité du build multi-étapes
Dépendances partagées entre les étapes
Les builds multi-étapes, tout en étant excellents pour réduire la taille finale de l’image, peuvent créer des vulnérabilités liées aux dépendances partagées lorsque plusieurs étapes reposent sur les mêmes images de base ou dépôts de packages compromis. Docker permet de diviser les Dockerfiles en plusieurs étapes. Par exemple, une étape pour compiler et construire l’application, qui peut ensuite être copiée dans les étapes suivantes.
Considérons un scénario où la étape de build et la étape de production tirent toutes deux depuis le même dépôt de packages compromis :
FROM python:3.9 as builder
RUN pip install build-tools==1.0.0
COPY requirements.txt .
RUN pip wheel --no-cache-dir -r requirements.txt
FROM python:3.9-slim
COPY --from=builder /wheels /tmp/wheels
RUN pip install --find-links /tmp/wheels app-dependencies
Si le package build-tools ou toute dépendance dans requirements.txt contient du code malveillant, cela peut influencer le processus de création des roues (wheels), injectant du code compromis dans les roues finales qui seront ensuite installées dans la étape de production.
La chaîne d’héritage comme vecteur d’attaque
Les attaquants avancés exploitent la nature d’héritage des images Docker via des compromis soigneusement élaborés des images de base. En publiant des images de base apparemment légitimes avec des portes dérobées subtiles, ils peuvent affecter des centaines ou des milliers d’images en aval qui héritent de ces fondations compromises.
L’attaque fonctionne en intégrant du code malveillant dormant dans des images de base courantes, puis en déclenchant un comportement malveillant via des motifs de fichiers ou des conditions d’environnement spécifiques lors des opérations COPY dans les images enfants :
# Image de base compromise avec logique cachée
FROM malicious/node:18-alpine
# Construction normale de l'application
COPY package.json .
RUN npm install
COPY app.js .
# L'image de base malveillante détecte app.js et active la fonctionnalité cachée
Analyse des couches et vulnérabilités forensiques
Le problème de mémoire persistante
Le système de fichiers en couches de Docker crée ce que les chercheurs en sécurité appellent la “mémoire persistante” — des données qui restent accessibles même après des commandes de suppression explicites. Ne mettez jamais de secrets ou d’identifiants dans les instructions du Dockerfile (variables d’environnement, args, ou hardcodés dans une commande). Faites particulièrement attention aux fichiers copiés dans le container.
Chaque couche maintient un enregistrement complet des changements du système de fichiers, ce qui signifie que des données sensibles copiées dans les premières couches restent récupérables de manière médico-légale tout au long de la durée de vie de l’image. Les outils modernes d’analyse de containers peuvent reconstruire l’historique complet des opérations sur les fichiers, exposant des secrets que les développeurs pensaient avoir effacés en toute sécurité.
Le problème s’aggrave avec la distribution et la mise en cache des registres de containers. Ces couches se propagent à travers plusieurs systèmes, créant de nombreux endroits où des données sensibles persistent, souvent longtemps après la destruction du container original.
Amplification des attaques via les registres
Les registres de containers servent involontairement de multiplicateurs de force pour les vulnérabilités basées sur Dockerfile. Lorsqu’une image compromise est poussée dans un registre, elle devient accessible à d’innombrables utilisateurs en aval qui font confiance à la validation de sécurité implicite du registre.
La nature temporelle du cache des registres signifie que même après la découverte de vulnérabilités et l’application de correctifs, d’anciennes versions en cache des couches compromises peuvent continuer à circuler. Cela crée une longue traîne d’exposition pouvant durer des mois ou des années après la première compromission.
Modèles de construction Dockerfile sécurisés
Mise en œuvre de contextes de build Zero-Trust
Une approche Zero-Trust pour la construction de Dockerfile commence par traiter chaque élément du contexte de build comme potentiellement hostile. Cela implique d’utiliser des fichiers .dockerignore stricts qui excluent explicitement plutôt qu’incluent des fichiers, et de structurer les projets pour que le contexte de build ne contienne que le minimum absolu nécessaire.
Utilisez plutôt les fonctionnalités intégrées de Docker comme les variables d’environnement, les secrets Docker, ou BuildKit pour une gestion sécurisée. Chaque méthode a ses cas d’usage appropriés, et le choix dépend des exigences de sécurité spécifiques et du contexte opérationnel de votre application.
Isolation de sécurité en multi-étapes
Les builds multi-étapes correctement implémentés doivent considérer chaque étape comme une frontière de sécurité. Cela signifie :
- Utiliser des images de base différentes pour les étapes de build et de production
- Mettre en œuvre une analyse explicite des dépendances à chaque transition d’étape
- Utiliser les capacités de montage de secrets de BuildKit pour une gestion sécurisée des identifiants
- Créer des étapes intermédiaires de vérification qui valident l’intégrité des artefacts copiés
Gestion des secrets avec BuildKit
BuildKit, la solution moderne de Docker, offre des capacités natives de gestion des secrets qui éliminent de nombreux risques traditionnels liés à COPY :
# syntax=docker/dockerfile:1
FROM python:3.9-slim
# Utilisation de montages de secrets au lieu de COPY
RUN --mount=type=secret,id=api_key \
curl -H "Authorization: Bearer $(cat /run/secrets/api_key)" \
https://api.example.com/secure-data | process_data
# Les secrets ne sont jamais écrits dans les couches du filesystem
COPY app.py /app/
Cette approche garantit que les données sensibles ne persistent jamais dans les couches d’image tout en fournissant l’accès nécessaire lors des opérations de build.
Stratégies de détection et de mitigation
Analyse automatique de sécurité des Dockerfiles
Mettre en œuvre des outils d’analyse de sécurité automatisés spécifiquement pour Dockerfiles nécessite des outils qui comprennent la nature en couches des builds de containers. Les outils d’analyse statique doivent être configurés pour détecter :
- Secrets codés en dur dans toute instruction
- Patterns potentiellement dangereux dans
COPY - Utilisation d’images de base non fiables
- Violations des frontières de sécurité en build multi-étapes
Détection en runtime des compromissions Dockerfile
Même avec des pratiques de build sécurisées, la détection en runtime reste cruciale. Pour se protéger contre des vulnérabilités connues comme Leaky Vessels, qui donnent généralement à l’attaquant un accès root au host, il est vital de maintenir à jour le host et Docker.
Les systèmes de surveillance doivent suivre : - Les connexions réseau inattendues depuis les containers - Les modèles d’accès aux fichiers qui ne correspondent pas au comportement attendu de l’application - L’exécution de processus indiquant une activation de porte dérobée - Les tentatives de communication container-vers-hôte
Procédures d’intervention d’urgence
Lorsqu’une compromission basée sur Dockerfile est détectée, les procédures doivent prendre en compte la distribution des images. Cela inclut :
- La suppression immédiate des images compromises de tous les registres
- La notification de tous les utilisateurs et systèmes en aval
- L’analyse médico-légale des couches affectées et de leur historique de distribution
- La reconstruction d’images propres à partir de processus de build vérifiés
L’avenir de la sécurité Dockerfile
Normes et pratiques émergentes
La communauté de la sécurité des containers développe de nouvelles normes pour la construction sécurisée. Celles-ci incluent :
- Exigences d’attestation de la chaîne d’approvisionnement pour les images de base
- Signature cryptographique des instructions Dockerfile individuelles
- Intégration avec la génération de billes de matériaux logiciels (SBOM)
- Réseau de containers Zero-Trust par défaut
Évolution technologique
Les futures versions de Docker devraient inclure des fonctionnalités de sécurité améliorées telles que :
- Analyse obligatoire des secrets lors du build
- Isolation renforcée entre les étapes de build
- Amélioration de la journalisation d’audit pour toutes les opérations
COPY - Intégration avec des services d’analyse de sécurité externes
Conclusion : Traiter les Dockerfiles comme du code critique pour la sécurité
Un seul container piraté peut révéler des informations sensibles, augmenter les niveaux d’accès ou même paralyser des systèmes entiers. La preuve est claire : les Dockerfiles doivent être traités avec la même rigueur de sécurité que tout autre code d’infrastructure critique.
La nature subtile des vulnérabilités basées sur Dockerfile les rend particulièrement dangereuses. Contrairement aux attaques en runtime qui déclenchent des systèmes de surveillance, les compromissions Dockerfile s’intègrent dans la fondation même du déploiement d’application, les rendant presque invisibles jusqu’à ce qu’il soit trop tard.
Les organisations doivent passer d’une vision de Docker comme simple outil de déploiement à une composante critique de leur architecture de sécurité. Cela implique de réaliser des revues de sécurité complètes des Dockerfiles, une analyse automatisée, et de considérer chaque instruction COPY comme un vecteur potentiel d’attaque.
L’avenir exige une combinaison de solutions techniques — outils améliorés, fonctionnalités Docker renforcées, capacités accrues d’analyse — et de changements culturels intégrant la sécurité dans chaque étape du développement de containers. Ce n’est qu’en reconnaissant et en traitant les dangers cachés dans nos Dockerfiles que nous pourrons construire des applications containerisées véritablement sécurisées.
Alors que la containerisation continue de dominer le déploiement logiciel moderne, les enjeux de la sécurité des Dockerfiles ne feront qu’augmenter. Rappelez-vous que le Dockerfile est en substance la documentation du processus de construction de votre application — une documentation que les attaquants peuvent lire aussi facilement que votre équipe de développement. Assurez-vous que cette histoire raconte une de sécurité, pas de vulnérabilité.
Le danger dans votre Dockerfile n’est pas seulement théorique — il est immédiat, persistant, et potentiellement catastrophique. La question n’est pas de savoir si vos Dockerfiles contiennent des vulnérabilités de sécurité, mais à quelle vitesse vous pouvez les détecter et les corriger avant qu’elles ne vous trouvent.
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.