P20 - DevSecOps : la sécurité dans toute la chaîne
Objectif
Comprendre l’approche DevSecOps (la sécurité intégrée à chaque étape, pas à la fin), savoir lire un score CVSS, produire une SBOM et scanner une image Docker avec Trivy et Dockle, puis durcir un
Dockerfile.
Source
Fiche rédigée à partir de cours de lidstah (module et 3 TP de lidstah).
1. Le scénario de départ
Une application est livrée. Elle contient : ton code, des centaines de dépendances (npm, pip…), des secrets (mots de passe de BDD, clés API), des images de conteneurs (avec tout un système Debian ou Alpine dedans) et des fichiers IaC (Terraform, Ansible). Quelques jours après, la base de données fuit. Où chercher ? Partout. DevSecOps, c’est vérifier tout ça automatiquement, à chaque modification, pour ne pas en arriver là.
2. Les 5 familles de tests automatiques
| Test | Ce qu’il cherche | Outils |
|---|---|---|
| SAST (Static) | Failles dans ton code source (injection SQL…) | Semgrep, SonarQube, Bandit (Python) |
| SCA (Software Composition Analysis) | Failles connues dans les dépendances | Trivy, osv-scanner, pip-audit |
| Scan IaC | Mauvaises configurations Terraform, Ansible, Kubernetes | Trivy config, Checkov, tfsec |
| DAST (Dynamic) | Failles visibles quand l’application tourne | OWASP ZAP |
| Secrets scanning | Mots de passe, clés API écrits en dur | Gitleaks, TruffleHog |
3. Le pipeline sécurisé
flowchart LR P["git push"] --> S1["SAST<br/>(code)"] --> S2["SCA<br/>(dépendances)"] --> S3["Scan IaC"] --> B["Build de l'image"] --> S4["Scan image<br/>(Trivy, Dockle)"] --> R["Registre<br/>(Harbor)"] --> PR["Production<br/>+ supervision"] S1 & S2 & S3 & S4 -.->|"faille critique"| X["⛔ build arrêté"]
Les 3 règles :
- Bloquer le critique (exécution de code à distance, secret en dur).
- Alerter sans bloquer pour le reste.
- Jamais de secrets en dur : HashiCorp Vault, Ansible Vault, SOPS, ou au minimum un fichier chiffré GPG.
4. Vocabulaire
| Terme | Signification |
|---|---|
| CVE | Identifiant public d’une vulnérabilité connue (ex. CVE-2024-3094, la porte dérobée de xz) |
| CVSS | Score de gravité de 0 à 10 : 0,1-3,9 faible · 4-6,9 moyen · 7-8,9 élevé · 9-10 critique |
| SBOM | Software Bill Of Materials : la liste des ingrédients d’un logiciel (fournisseur, composant, version, dépendances, date). Ce n’est pas un scanner, mais un scanner peut la lire |
| Supply chain | Chaîne d’approvisionnement : d’où vient chaque composant, est-il signé, par qui |
| Security by design | Moindre privilège (pas de root), défense en profondeur (chaque couche protégée), sécurisé par défaut (seuls les ports utiles ouverts) |
| Analyse de risques | Menaces (qui ?) × vulnérabilités (par où ?) × impact (combien ça coûte ?) → on protège d’abord ce qui compte le plus |
Les 5 métriques DevSecOps : MTTD (temps moyen pour détecter, viser < 24 h), MTTR (temps moyen pour corriger, viser < 7 jours), taux de détection avant la production, taux de faux positifs (trop de bruit = alertes ignorées), couverture des scans.
5. TP : scanner une image
sudo apt install docker.io
# SBOM avec Syft (liste des paquets de l'image)
docker run --rm anchore/syft wordpress:6.9.1-php8.4-apache
# vulnérabilités avec Trivy
mkdir -p trivycache
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v ./trivycache:/root/.cache/ \
aquasec/trivy image --severity HIGH,CRITICAL wordpress:6.9.1-php8.4-apache
# mauvaises pratiques du Dockerfile / de l'image avec Dockle
dockle wordpress:6.9.1-php8.4-apache
# scanner des fichiers Terraform / Kubernetes / Dockerfile
docker run --rm -v ./mon-projet:/projet aquasec/trivy config /projetÀ comparer : la même application sur une base debian:trixie, alpine ou une image distroless : moins il y a de paquets, moins il y a de CVE.
Harbor (registre d’images, installé par Helm sur K3s) fait tout ça automatiquement à chaque docker push : SBOM + scan Trivy intégré + blocage des images trop vulnérables.
6. Durcir un Dockerfile
L’exemple « à ne pas faire » du TP :
FROM alpine:latest
RUN apk update
RUN apk upgrade
RUN apk add git nginx
RUN git clone https://github.com/... /usr/share/nginx/html
COPY ./default.conf /etc/nginx/http.d/default.confProblèmes : tag latest (pas reproductible), tourne en root, git reste dans l’image finale, cache des paquets conservé, plusieurs couches inutiles.
Version durcie :
# étape 1 : récupérer le contenu (git ne sera PAS dans l'image finale)
FROM alpine:3.22 AS source
RUN apk add --no-cache git \
&& git clone --depth 1 https://github.com/Werkstattl/quick-dungeon-crawler-rpg-od /site
# étape 2 : image finale minimale, nginx sans root
FROM nginxinc/nginx-unprivileged:1.27-alpine
COPY --from=source --chown=101:101 /site /usr/share/nginx/html
USER 101
EXPOSE 8080
HEALTHCHECK CMD wget -qO- http://127.0.0.1:8080/ || exit 1Exercices
- Une CVE a un score CVSS de 9,8 dans une bibliothèque que ton application utilise. Que fait le pipeline ?
- Pourquoi une SBOM est-elle utile le jour où une nouvelle faille est publiée ?
- Cite trois améliorations de sécurité d’un Dockerfile.
Correction
- C’est critique (≥ 9) : le build est bloqué jusqu’à la mise à jour de la bibliothèque.
- On sait immédiatement quelles applications contiennent le composant touché, sans tout réexaminer à la main.
- Version d’image fixée (pas
latest), utilisateur non-root (USER), build multi-étapes pour ne pas embarquer les outils,--no-cachepour les paquets, image de base minimale,HEALTHCHECK.
Voir aussi
- V05 - Docker · P08 - Conteneurs avancés (Docker, Kubernetes) · P19 - Kubernetes · P10 - Automatisation avec Ansible · O04 - Git et GitHub · P09 - Cybersécurité (RGPD, ANSSI, PKI)
- Cours complet : cours de lidstah · cours de lidstah · cours de lidstah
- Retour : P00 - Programme pas encore vu