Le scan de sécurité des conteneurs avec Trivy est devenu le standard de facto pour détecter les vulnérabilités dans les images Docker avant qu’elles n’atteignent la production. Si vous vous êtes déjà demandé comment les attaquants exploitent des CVE connus dans des images de base comme ubuntu:20.04 ou node:18, ou si votre Dockerfile expose des secrets, Trivy vous donne la réponse en quelques secondes. Ce guide couvre l’installation, les stratégies de scan, l’intégration CI/CD et comment interpréter et agir sur les découvertes de Trivy sans se noyer dans les faux positifs.

Prérequis

  • Docker installé et en cours d’exécution (Docker 20.10+)
  • Station de travail Linux, macOS ou Windows (WSL2)
  • Familiarité de base avec les images Docker et les Dockerfiles
  • Une plateforme CI/CD (GitHub Actions, GitLab CI ou Jenkins) pour l’intégration de pipeline
  • Accès root ou sudo pour l’installation de Trivy au niveau système (ou utiliser l’installation du binaire)

Installation de Trivy

Trivy est distribué comme un binaire statique unique sans dépendances externes. Le chemin le plus rapide sur Linux :

curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
trivy --version

Sur Ubuntu/Debian, vous pouvez ajouter le dépôt apt d’Aqua Security pour des mises à jour gérées :

sudo apt-get install wget apt-transport-https gnupg lsb-release -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy -y

Sur macOS avec Homebrew : brew install trivy

Trivy télécharge sa base de données de vulnérabilités à la première exécution. Forcez une mise à jour de la base à tout moment avec trivy image --download-db-only.

Scanner les Images Docker pour les Vulnérabilités

La commande principale est simple :

trivy image nginx:latest

Trivy télécharge l’image si elle n’est pas dans le cache local, décompresse les couches et vérifie chaque paquet du système installé et chaque dépendance de langage dans sa base de données de vulnérabilités (NVD, GitHub Advisory, Alpine secdb et autres). La sortie affiche les IDs de CVE, la sévérité, la version installée et la version corrigée lorsqu’elle est disponible.

Filtrage par Sévérité

Par défaut, Trivy affiche toutes les sévérités de UNKNOWN à CRITICAL. En pratique, vous souhaitez vous concentrer sur les découvertes actionnables :

trivy image --severity HIGH,CRITICAL nginx:latest

Ignorer les Vulnérabilités Sans Correction

De nombreux CVE n’ont pas encore de correction disponible. Utilisez --ignore-unfixed pour les ignorer et vous concentrer sur ce que vous pouvez réellement remédier :

trivy image --severity HIGH,CRITICAL --ignore-unfixed nginx:latest

Formats de Sortie

Trivy prend en charge plusieurs formats de sortie pour différents consommateurs :

# Tableau lisible par l'humain (par défaut)
trivy image nginx:latest

# JSON pour le traitement programmatique
trivy image --format json --output results.json nginx:latest

# SARIF pour l'intégration avec l'onglet Sécurité de GitHub
trivy image --format sarif --output results.sarif nginx:latest

# SBOM CycloneDX
trivy image --format cyclonedx --output sbom.json nginx:latest

Le format SARIF s’intègre directement avec l’onglet Sécurité de GitHub, affichant des annotations de vulnérabilités en ligne dans les pull requests.

Scanner les Dockerfiles et Mauvaises Configurations IaC

Le scanner config de Trivy vérifie les Dockerfiles, les manifestes Kubernetes, Terraform et les charts Helm pour les mauvaises configurations de sécurité avant leur déploiement :

# Scanner un Dockerfile
trivy config ./Dockerfile

# Scanner un répertoire complet (manifestes Kubernetes, Terraform)
trivy config ./k8s/

# Scanner des charts Helm
trivy config --helm-values values.yaml ./charts/myapp

Les découvertes courantes dans les Dockerfiles incluent : exécution en tant que root, utilisation de ADD au lieu de COPY, absence de HEALTHCHECK, exposition de ports sensibles et non-fixation des digests d’images de base.

Détection des Secrets et Données Sensibles

Trivy peut scanner les couches d’images et les systèmes de fichiers pour détecter des secrets accidentellement intégrés :

# Activer le scan de secrets sur une image
trivy image --scanners secret nginx:latest

# Scanner un répertoire local pour les secrets
trivy fs --scanners secret ./src/

Trivy détecte les clés AWS, les tokens GitHub, les clés SSH privées, les chaînes de connexion de bases de données et des centaines d’autres modèles de secrets. C’est particulièrement précieux pour attraper les secrets commis dans le code source qui se sont retrouvés dans une couche Docker.

Comparaison avec les Alternatives

FonctionnalitéTrivyGrypeSnykClair
CVE des paquets du SOOuiOuiOuiOui
Dépendances de langageOuiOuiOuiNon
Mauvaises configs IaCOuiNonOuiNon
Scan de secretsOuiNonOuiNon
Génération de SBOMOuiOuiOuiNon
LicenceApache 2.0Apache 2.0PropriétaireApache 2.0
Intégration CI/CDNativeNativeNativeLimitée
Mode hors ligneOuiOuiNonPartiel

L’avantage de Trivy est son étendue — il combine le scan de vulnérabilités, la détection de mauvaises configurations, le scan de secrets et la génération de SBOM dans un seul binaire sans nécessiter de serveur en cours d’exécution ni de base de données.

Intégration de Trivy dans les Pipelines CI/CD

GitHub Actions

name: Scan de Sécurité des Conteneurs

on:
  push:
    branches: [main]
  pull_request:

jobs:
  trivy-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Construire l'image Docker
        run: docker build -t myapp:${{ github.sha }} .

      - name: Exécuter le scanner de vulnérabilités Trivy
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          format: sarif
          output: trivy-results.sarif
          severity: HIGH,CRITICAL
          exit-code: 1
          ignore-unfixed: true

      - name: Téléverser les résultats Trivy vers l'onglet Sécurité GitHub
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: trivy-results.sarif

Le paramètre exit-code: 1 fait échouer le pipeline lorsque des CVE critiques ou élevés sont trouvés. if: always() sur le téléversement SARIF garantit que les résultats sont visibles même lorsque l’étape de scan échoue.

GitLab CI

trivy-scan:
  image: aquasec/trivy:latest
  stage: test
  script:
    - trivy image --exit-code 1 --severity CRITICAL --ignore-unfixed $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  allow_failure: false

Scénario Réel

Vous avez une application en production exécutant node:16 comme image de base. Votre équipe de sécurité signale que le pipeline CI/CD ne valide jamais les images de conteneur avant le déploiement. Vous avez 48 heures pour implémenter une porte de scan.

Étape 1 — Auditer l’image actuelle :

trivy image node:16 --severity HIGH,CRITICAL --ignore-unfixed

Cela révèle 47 CVE HIGH et 12 CRITICAL dans l’image de base — la plupart corrigés en passant à node:18-alpine.

Étape 2 — Mettre à jour le Dockerfile :

# Avant
FROM node:16

# Après
FROM node:18-alpine

Étape 3 — Rescanner pour confirmer la correction :

trivy image node:18-alpine --severity HIGH,CRITICAL --ignore-unfixed

La variante alpine réduit le nombre de CVE de 59 à 3 (tous sans correction).

Étape 4 — Ajouter la porte CI :

Ajoutez le workflow GitHub Actions ci-dessus. Toutes les futures PRs seront bloquées si des CVE CRITICAL sont introduits.

Étape 5 — Scanner aussi l’IaC :

trivy config ./k8s/ --severity HIGH,CRITICAL

Cela révèle deux problèmes : un déploiement s’exécutant en tant que root et un paramètre de contexte de sécurité readOnlyRootFilesystem manquant.

Pièges et Cas Particuliers

Obsolescence de la base de données de vulnérabilités : Trivy met sa base de données en cache localement. Dans les environnements CI, exécutez trivy image --download-db-only comme étape de cache séparée pour éviter les téléchargements redondants.

Authentification sur les registres privés : Exportez les credentials en variables d’environnement avant de scanner :

export TRIVY_USERNAME=monutilisateur
export TRIVY_PASSWORD=monmotdepasse
trivy image monregistre.exemple.com/monapp:latest

Faux positifs : Certains CVE sont signalés dans des bibliothèques que votre application n’appelle jamais. Utilisez .trivyignore pour supprimer les faux positifs connus :

# .trivyignore
CVE-2022-12345  # Non exploitable — bibliothèque non appelée à l'exécution

Alpine musl vs glibc : Les images basées sur Alpine signalent moins de CVE car Alpine utilise musl libc et l’équipe de sécurité d’Alpine corrige agressivement. Ce n’est pas une couverture “manquante” — cela reflète de véritables différences dans l’écosystème des bibliothèques.

Images multi-architecture : Spécifiez toujours la plateforme lors du scan d’images multi-arch pour obtenir des résultats corrects : trivy image --platform linux/amd64 myapp:latest.

Trivy vs sécurité à l’exécution : Trivy trouve les vulnérabilités au moment de la construction. Il ne remplace pas les outils de sécurité à l’exécution comme Falco qui détectent les comportements inattendus dans les conteneurs en cours d’exécution.

Résolution de Problèmes

Erreur “No such image” : Trivy ne peut pas trouver l’image localement et ne peut pas la télécharger. Confirmez le nom de l’image, le tag et les credentials du registre.

Échecs de téléchargement de base de données en environnement isolé : Téléchargez le bundle de base de données sur une machine connectée à Internet avec trivy image --download-db-only, puis transférez le répertoire ~/.cache/trivy/ vers l’hôte isolé.

Utilisation mémoire élevée sur de grandes images : Utilisez --parallel 1 pour réduire le traitement simultané des couches : trivy image --parallel 1 myapp:latest.

Code de sortie 1 mais aucun CVE critique affiché : Vérifiez si --ignore-unfixed est omis — les CVE critiques sans correction peuvent déclencher le code de sortie même si vous espériez ne voir que des problèmes corrigeables.

Timeout de scan en CI : Définissez TRIVY_TIMEOUT=10m pour étendre le timeout par défaut de 5 minutes pour les grandes images.

Résumé

  • Trivy est un scanner à binaire unique couvrant les CVE, les mauvaises configurations, les secrets et la génération de SBOM
  • Exécutez trivy image --severity HIGH,CRITICAL --ignore-unfixed myapp:latest comme scan de base
  • Utilisez --exit-code 1 en CI/CD pour bloquer les déploiements avec des vulnérabilités critiques
  • Combinez trivy image (runtime) avec trivy config (Dockerfile/IaC) pour une couverture complète
  • Les images basées sur Alpine réduisent considérablement la surface CVE
  • Utilisez .trivyignore pour supprimer les faux positifs confirmés et réduire la fatigue aux alertes
  • Téléversez les résultats SARIF vers l’onglet Sécurité de GitHub pour des annotations inline dans les PRs
  • Trivy ne remplace pas la sécurité à l’exécution — associez-le à Falco pour une défense en profondeur

Articles Connexes