Exercice 06 : Projet Capstone - Sécuriser un Pipeline CI/CD et ses Images Docker
🎯 Objectifs
À la fin de cet exercice, vous serez capable de :
- ✅ Scanner les vulnérabilités d'une image Docker avec
Trivy - ✅ Détecter et prévenir les secrets commités avec
git-secretsoutrufflehog - ✅ Intégrer un scan SAST (analyse statique) dans le pipeline GitHub Actions
- ✅ Générer un SBOM (Software Bill of Materials) pour une image Docker
- ✅ Appliquer les principes du moindre privilège dans un Dockerfile
Durée estimée : 1h
Difficulté : ⭐⭐⭐⭐⭐ (Expert)
Prérequis :
- Docker installé, notions de GitHub Actions
- Module Sécurité DevOps complété (scanning, secrets, supply chain)
📖 Contexte
Votre pipeline CI déploie des images Docker en production sans aucun contrôle de sécurité. Vous allez intégrer les outils de la sécurité DevSecOps pour détecter les vulnérabilités, les secrets commités, et les problèmes de configuration avant qu'ils n'atteignent la production.
📋 Énoncé
Auditez et sécurisez un pipeline CI/CD en intégrant les scans de sécurité, la gestion des secrets, et les bonnes pratiques de supply chain security.
🧭 Déroulement de l'exercice
Tâche 1 : Scanner une image Docker avec Trivy
Installez Trivy et scannez l'image python:3.8 (image intentionnellement ancienne avec des vulnérabilités) et l'image python:3.12-slim (image récente). Comparez les résultats.
Indice :
trivy image python:3.8scanne toutes les vulnérabilités.trivy image --severity HIGH,CRITICAL python:3.8filtre sur les severités importantes.trivy image --format json python:3.8 | jq '.Results[].Vulnerabilities | length'compte les vulnérabilités.
Vérification : python:3.8 affiche significativement plus de vulnérabilités HIGH/CRITICAL que python:3.12-slim. Notez la différence de score.
Tâche 2 : Scanner le système de fichiers et les dépendances
Créez un projet Python avec un requirements.txt contenant des dépendances volontairement anciennes (django==3.2.0, pillow==9.0.0). Scannez les dépendances avec Trivy.
Indice :
trivy fs --scanners vuln .scanne le système de fichiers local, y compris les fichiers de dépendances (requirements.txt,package.json, etc.). Trivy identifie les CVE associées aux versions de dépendances déclarées.
Vérification : trivy fs --scanners vuln --format table . liste les CVE pour Django 3.2 et Pillow 9.0.
Tâche 3 : Détecter des secrets dans le code
Créez intentionnellement un fichier config.py contenant des "secrets" en clair (API key fictive, mot de passe). Utilisez trufflehog (ou git-secrets) pour détecter ces secrets.
Indice :
trufflehog filesystem .scanne les fichiers locaux. Alternativement :docker run --rm -v $(pwd):/pwd trufflesecurity/trufflehog:latest filesystem /pwd. Trivy peut aussi détecter les secrets :trivy fs --scanners secret ..
Vérification : Le scan détecte les patterns secrets dans config.py. Ne committez jamais ce fichier (ajoutez-le au .gitignore).
Tâche 4 : Sécuriser le Dockerfile
Prenez ce Dockerfile non sécurisé et corrigez-le :
# Dockerfile non sécurisé (à corriger)
FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3 python3-pip
COPY . /app
RUN pip3 install -r /app/requirements.txt
CMD ["python3", "/app/server.py"]Problèmes à corriger :
- Image trop lourde et non fixée (
ubuntu:latest→ utiliserpython:3.12-slim) - Processus tournant en root (ajouter un utilisateur non-root)
- Layer de dépendances mal optimisé
- Pas de
--no-cache-dirpour pip
Indice : Un Dockerfile sécurisé : image de base fixée et minimale,
COPY requirements.txtAVANTCOPY .,pip install --no-cache-dir,adduser --system,USER <non-root>.
Vérification : trivy image --severity HIGH,CRITICAL <votre-image> retourne 0 vulnérabilités HIGH/CRITICAL. docker inspect <votre-image> --format '{{.Config.User}}' ne retourne pas root.
Tâche 5 : Générer un SBOM
Générez un SBOM (Software Bill of Materials) pour votre image Docker corrigée, aux formats CycloneDX et SPDX. Le SBOM liste tous les composants de l'image avec leurs versions et licences.
Indice :
trivy image --format cyclonedx --output sbom.json <votre-image>génère le SBOM au format CycloneDX.trivy image --format spdx-json --output sbom-spdx.json <votre-image>génère en SPDX. Un SBOM est obligatoire pour certains secteurs réglementés (finance, santé, gouvernement).
Vérification : cat sbom.json | python3 -m json.tool | head -30 affiche la structure CycloneDX avec les composants. cat sbom-spdx.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(len(d['packages']), 'packages')" affiche le nombre de packages.
Tâche 6 : Intégrer la sécurité dans GitHub Actions
Créez .github/workflows/security.yml qui :
- Se déclenche sur push et PR
- Scanne l'image Docker avec Trivy et bloque si des HIGH/CRITICAL sont trouvées
- Scanne les secrets avec
trufflehog - Génère et publie le SBOM comme artefact
- Publie les résultats Trivy en format SARIF dans l'onglet Security de GitHub
Indice : Utilisez l'action
aquasecurity/trivy-action@masteravecexit-code: '1'pour bloquer le pipeline. Le format SARIF (--format sarif) est uploadé avecgithub/codeql-action/upload-sarif@v3pour apparaître dans l'onglet Security.
Vérification : Sur une PR avec une image vulnérable, le workflow échoue avec les CVE listées. L'onglet Security de GitHub affiche les vulnérabilités.
🗂️ Mini-Projet : Pipeline DevSecOps complet
Arborescence :
devsecops-demo/
├── .github/
│ └── workflows/
│ └── security.yml
├── server.py
├── requirements.txt
├── Dockerfile
└── .gitignore ← contient config.py, .env, *.keyAudit de sécurité complet :
# 1. Scanner l'image avant et après correction
trivy image python:3.8 --severity HIGH,CRITICAL
trivy image python:3.12-slim --severity HIGH,CRITICAL
# 2. Scanner les dépendances
trivy fs --scanners vuln --format table .
# 3. Scanner les secrets (NE PAS committer les résultats !)
trivy fs --scanners secret .
# 4. Scanner le Dockerfile pour les mauvaises pratiques
trivy config Dockerfile
# 5. Générer le SBOM
docker build -t secure-app:v1 .
trivy image --format cyclonedx --output sbom.json secure-app:v1
trivy image --format spdx-json --output sbom-spdx.json secure-app:v1
# 6. Résumé de sécurité
trivy image --format table --severity HIGH,CRITICAL secure-app:v1Checkpoints de validation :
trivy image python:3.8affiche plus de CVE quepython:3.12-slimtrivy fs --scanners vuln .détecte des CVE dansrequirements.txttrivy fs --scanners secret .détecte les secrets dansconfig.pytrivy config Dockerfileretourne 0 erreurs sur le Dockerfile corrigédocker inspect secure-app:v1 --format '{{.Config.User}}'≠rootsbom.jsonetsbom-spdx.jsonsont générés- Le workflow GitHub Actions bloque sur une image vulnérable