La sécurité des conteneurs commence par l'image de base.
Mais il y a un hic :
- Le simple fait de passer à la "dernière" version d'une image de base peut endommager votre application.
- Vous êtes contraint de choisir entre l'expédition de vulnérabilités connues et des journées entières consacrées à la résolution de problèmes de compatibilité.
- Et souvent, vous n'êtes même pas sûr qu'une mise à niveau en vaille la peine.
Dans cet article, nous allons voir pourquoi la mise à jour des images de base est plus difficile qu'il n'y paraît, nous allons voir des exemples concrets et nous allons montrer comment vous pouvez automatiser des mises à jour sûres et intelligentes sans casser votre application.
Le problème : "Il suffit de mettre à jour votre image de base" - Plus facile à dire qu'à faire
Si vous lisez ceci, vous avez probablement cherché sur Google quelque chose comme "Comment sécuriser vos conteneurs" et le premier point de chaque article généré par l'IA que vous avez lu est le suivant : mettez à jour votre image de base. C'est simple, non ? Pas si vite.
Votre image de base est votre point central de sécurité, si votre image de base contient des vulnérabilités, alors votre application porte ces vulnérabilités avec elle. Jouons ce scénario.
Vous lancez un scan de votre image de conteneur et un CVE de haute sévérité est trouvé. La recommandation utile est de mettre à jour l'image de base, ce qui est fantastique, vous aurez terminé avant le déjeuner.
⚠️ CVE-2023-37920 trouvé dans ubuntu :20.04
Sévérité: Élevée
Corrigé dans: 22.04
Recommandation: Mettre à jour l'image de base
...mais vous découvrez un problème.
En passant aveuglément de ubuntu:20.04
à ubuntu:22.04
Votre demande est rejetée.
Examinons quelques exemples de surimpression d'une image de base et ce qui se passe dans la réalité.
Exemple 1 : Un fichier Docker qui se casse la figure après une mise à jour
Fichier Docker initial :
FROM python:3.8-buster
Exécuter apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2
COPY . /appCMD ["python", "app.py"]
L'équipe se met à niveau :
FROM python:3.11-bookworm
Exécuter apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2COPY . /appCMD ["python", "app.py"]
Résultat :
psycopg2==2.8.6
ne compile pas contre les versions plus récentes delibpq
les en-têtes surrat de bibliothèque.
flask==1.1.2
ne prend pas en chargePython 3.11
les fonctionnalités d'exécution (les API obsolètes sont interrompues).- La construction est interrompue dans le CI.
- Votre équipe de développement est en colère et votre déjeuner est gâché.
Exemple 2 : mises à jour de l'image de base introduisant des bogues d'exécution subtils
Original :
FROM node:14-busterCOPY. /app
RUN npm ci
CMD ["node", "server.js"]
Mise à niveau vers :
FROM node:20-bullseye
COPY . /app
RUN npm ci
CMD ["node", "server.js"]
Problème d'exécution :
nœud:20
utilise des produits plus récentsOpenSSL
versions - la vérification stricte de TLS casse les anciennes configurations d'axios.- L'application lance
UNABLE_TO_VERIFY_LEAF_SIGNATURE
erreurs lors de l'exécutionHTTP
les appels vers les services existants.
Pourquoi le "dernier cri" est un piège
L'écosystème Docker encourage l'utilisation des dernières balises ou des versions les plus récentes. Mais cela signifie souvent que votre application qui fonctionnait le lundi tombe soudainement en panne le mardi. Il s'agit souvent d'un piège qui entraîne des maux de tête, des pannes et un ralentissement du développement, car vous passez du temps à corriger les bogues.
La solution est donc évidemment d'épingler une version mineure que vous avez testée.... Pas si vite, car vous entrez maintenant dans le jeu de la sécurité à la carte, où vous découvrirez sans cesse de nouvelles CVE qui pourraient vous rendre vulnérable.
Paralysie décisionnelle : Faut-il ou non procéder à une mise à niveau ?
Les équipes chargées de la sécurité insistent pour que les mises à jour soient effectuées.
Les développeurs repoussent les mises à jour pour des raisons de stabilité.
Qui a raison ? Cela dépend.
MAIS, pour comprendre la décision, vous devez examiner toutes les options, ce qui signifie créer une feuille de calcul massive de toutes les versions, des risques de sécurité, des risques de stabilité et de la disponibilité.
Voyons à quoi cela pourrait ressembler.
Vous vous retrouvez donc face à des choix complexes, médiocres et impossibles.
- Rester sur l'ancienne image et accepter les vulnérabilités
- Mettre à jour et casser votre application, en risquant des arrêts de production
- Tentative de test de compatibilité manuel - jours de travail
Le processus de mise à niveau manuelle :
Si vous le faites à la main, voici à quoi cela ressemble :
- Vérifier les CVE :
trivy image python:3.8-buster
- Recherchez chaque CVE : est-il accessible dans votre contexte d'application ?
- Choisir un candidat à la mise à niveau
- Tester la nouvelle image :
- Construire
- Exécuter les tests unitaires
- Exécuter les tests d'intégration
- En cas d'échec, essayez de corriger le code ou de mettre à jour les bibliothèques.
- Répéter l'opération pour chaque récipient.
C'est épuisant.
Le coût de l'immobilisme
Vous pensez peut-être que "si ce n'est pas cassé, il ne faut pas le réparer".
Mais les vulnérabilités non corrigées des conteneurs contribuent massivement aux failles de sécurité : "87 % des images de conteneurs fonctionnant en production présentaient au moins une vulnérabilité critique ou de grande gravité" .
Il existe également de nombreux exploits connus dans les images de base populaires.
- Faille de sécurité dans les chemins d'accès à Unzip (
CVE-2020-27350
) - sont restés dans des millions de conteneurs pendant des années. - Heartbleed (
CVE-2014-0160
) sont restés dans les anciens conteneurs bien après les corrections officielles. PHP-FPM RCE
(CVE-2019-11043
) permettent à des attaquants distants d'exécuter du code arbitraire par le biais de requêtes HTTP élaborées et étaient extrêmement répandues dans les images de base de conteneurs avecPHP-FPM préinstallé
avant d'être patché
L'utilité de notre fonction Auto-Fix
Pour résoudre ce problème, Aikido Security a mis en place une fonction d'auto-fixation des conteneurs, car nous vivons aussi cette situation.
La fonctionnalité fonctionne comme suit : Aikido scanne vos images et vos conteneurs à la recherche de vulnérabilités. Si (ou plus probablement quand) nous trouvons des vulnérabilités, comme toujours nous vous alertons, puis au lieu de vous crier de mettre à jour votre image de base, nous vous fournissons différentes options. Nous créons un tableau qui vous permet de savoir quelle version de l'image de base résoudra quelles CVEs, de cette façon vous pouvez très rapidement voir qu'une modification mineure peut supprimer toutes ou une majorité de CVEs élevées, ce qui signifie qu'il s'agit d'une mise à jour adéquate de l'image de base.
Si la mise à jour est mineure, vous pouvez automatiquement créer une demande d'extension pour augmenter la version.
Ce sont des heures de travail économisées
Conclusion :
- La mise à jour des images de base des conteneurs est vraiment difficile.
- Le conseil de se contenter d'une mise à niveau simplifie à l'extrême un processus complexe et porteur de risques.
- Vos équipes ont raison d'être prudentes, mais elles ne devraient pas avoir à choisir entre sécurité et stabilité.
- Le conteneur autofix d'Aikido fait le travail pour vous afin que vous puissiez prendre une décision en toute connaissance de cause.
- Ainsi, la prochaine fois que vous verrez une alerte de vulnérabilité de l'image de base, vous ne paniquerez pas. Vous obtiendrez une RP.