Gestion des vulnérabilités : DefectDojo, Dependency-Track & VEX
Objectifs pédagogiques
- Passer d'une pile de rapports de scanners à un programme de gestion des vulnérabilités piloté
- Prioriser au-delà du score CVSS, avec la probabilité d'exploitation et le contexte
- Centraliser, dédupliquer et suivre les constats dans DefectDojo, alimenté par la CI
- Gouverner les exceptions : faux positifs justifiés, acceptations de risque datées
- Surveiller les SBOM dans le temps et déclarer l'exploitabilité réelle avec VEX
Du rapport au pilotage
Le problème
- Chaque pipeline produit des rapports : secrets, SAST, dépendances, image, DAST
- Une même vulnérabilité remontée par trois outils devient trois alertes
- Les rapports restent dans les artefacts CI, et personne ne sait ce qui a été traité
- Des centaines de constats non triés finissent par être ignorés : c'est la fatigue d'alerte
- Une CVE publiée après le déploiement ne déclenche aucun rapport
- Résultat : beaucoup de scanners, peu de sécurité
Le cycle de vie d'une vulnérabilité
- Détection : un scanner remonte un constat
- Déduplication : un constat déjà connu n'est pas recréé
- Qualification : vrai positif, faux positif, hors périmètre
- Priorisation : sévérité, exploitabilité, exposition
- Traitement : corriger, atténuer, accepter le risque ou le transférer
- Vérification : le scan suivant confirme la correction
-
Clôture : avec une trace consultable par l'audit
-
Chaque étape a un responsable et un délai
Prioriser
Le score CVSS ne suffit pas
- CVSS : sévérité théorique de la vulnérabilité, indépendante de votre contexte
- EPSS (FIRST) : probabilité d'exploitation dans les 30 prochains jours, mise à jour quotidiennement
- KEV (CISA) : catalogue des vulnérabilités exploitées activement
- Contexte : le composant est-il exposé, joignable, chargé à l'exécution, manipule-t-il des données sensibles ?
- Une vulnérabilité critique non exploitable compte moins qu'une haute présente dans le catalogue KEV et exposée sur Internet
Exemple de matrice de priorité
| Priorité | Critère | Délai de traitement |
| P1 | Présente dans KEV, ou EPSS élevé, et composant exposé | 48 h |
| P2 | Critique, ou haute et exposée | 7 jours |
| P3 | Haute non exposée, ou moyenne exposée | 30 jours |
| P4 | Autres | 90 jours |
- La matrice est une décision de la PSSI, pas un choix d'outil
- Elle est documentée, versionnée et revue quand les menaces évoluent
- Un délai maximal de correction par sévérité ou par priorité
- Le compteur démarre à la détection, pas au triage
- Un constat hors SLA est visible : il remonte dans les indicateurs et dans le reporting
- Prolonger un délai passe par une acceptation de risque formelle, jamais par un oubli
- DefectDojo calcule l'échéance de chaque constat à partir de la configuration de SLA du produit
DefectDojo
DefectDojo en bref
- Plateforme open source de gestion des vulnérabilités, projet phare de l'OWASP
- Plus de 200 parseurs de rapports : Trivy, ZAP, Gitleaks, Semgrep, SonarQube, CycloneDX
- API v2 complète : l'import se fait depuis la CI, sans intervention humaine
- Déduplication, statuts, acceptations de risque, SLA, indicateurs
- Déploiement par docker compose ou Kubernetes ; une offre commerciale existe à côté
- Gourmand en ressources : prévoir plusieurs gigaoctets de RAM, ou une instance partagée
Le modèle de données
| Objet | Rôle | Exemple SecurePay |
| Product Type | regroupement métier | Paiement |
| Product | application ou service | SecurePay API |
| Engagement | période ou contexte d'analyse | CI staging, CI production, pentest annuel |
| Test | un import d'un scanner | Trivy image, ZAP staging |
| Finding | un constat | CVE-2021-22945 dans curl |
- Les SLA et les utilisateurs autorisés se configurent au niveau du produit
- Dans les versions récentes de l'édition open source, les rôles fins par produit et les groupes relèvent de l'offre commerciale
Importer depuis la CI
curl -sf -X POST "$DOJO_URL/api/v2/reimport-scan/" \
-H "Authorization: Token $DOJO_TOKEN" \
-F scan_type="Trivy Scan" \
-F file=@trivy-image.json \
-F product_type_name="Paiement" \
-F product_name="SecurePay API" \
-F engagement_name="CI staging" \
-F test_title="Trivy image" \
-F environment="Staging" \
-F auto_create_context=true \
-F close_old_findings=true \
-F minimum_severity=Low
- Les valeurs de
scan_type sont strictes : Trivy Scan, ZAP Scan, Gitleaks Scan, Semgrep JSON Report, CycloneDX Scan - Le jeton appartient à un utilisateur dédié, non administrateur, autorisé sur ce seul produit, et il est rangé dans un coffre
Import ou réimport
import-scan crée un nouveau test à chaque appel reimport-scan met à jour le test existant du même engagement - les nouveaux constats sont ajoutés
- les constats toujours présents sont conservés, avec leur historique de triage
- avec
close_old_findings, ceux qui ont disparu sont clôturés comme corrigés - En CI, le réimport est la règle : un pipeline relancé ne duplique rien
auto_create_context crée produit et engagement au premier passage
Déduplication
- Chaque parseur déclare son algorithme : empreinte calculée sur des champs choisis, identifiant fourni par l'outil, ou les deux
- Elle s'applique au sein du produit, ou de l'engagement avec
deduplication_on_engagement - Un constat dupliqué est rattaché à l'original au lieu d'alourdir la liste
- C'est elle qui transforme 1 400 lignes en quelques dizaines de constats uniques
- Une déduplication mal réglée se repère vite : un pipeline relancé fait grossir le backlog
Qualifier un constat
| Statut | Signification |
| Active / Verified | vrai positif confirmé, à traiter |
| False Positive | le scanner se trompe, preuve à l'appui |
| Out of Scope | hors du périmètre du produit |
| Risk Accepted | risque connu et accepté formellement, pour une durée donnée |
| Mitigated | corrigé, confirmé par un scan ultérieur |
- Un faux positif porte une justification technique vérifiable, validée par une seconde personne
- L'historique des faux positifs peut marquer automatiquement les réapparitions du même constat
Accepter un risque
- Un propriétaire du risque, pas forcément un technicien
- Une décision : accepter, atténuer, transférer
- Des mesures compensatoires décrites
- Une date d'expiration : à l'échéance, DefectDojo réactive les constats concernés par défaut
- Une acceptation sans date est une dette cachée
- Les acceptations expirées alimentent la revue mensuelle des risques
SBOM, Dependency-Track & VEX
Surveiller dans le temps
- Un scan photographie les vulnérabilités connues le jour du build
- Un SBOM inventorie les composants et reste valable tant que l'artefact ne change pas
- Confronter en continu les SBOM aux nouvelles publications révèle les CVE apparues après le déploiement
- Dependency-Track (OWASP) fait exactement cela : import des SBOM, analyse continue, politiques, notifications
- Dans le cluster, Trivy Operator rescanne aussi les images en cours d'exécution
- Les deux approches se complètent : l'inventaire des livrables et l'état réel de la production
Alimenter Dependency-Track depuis la CI
curl -sf -X POST "$DTRACK_URL/api/v1/bom" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-F autoCreate=true \
-F projectName="securepay-api" \
-F projectVersion="$CI_COMMIT_SHORT_SHA" \
-F bom=@sbom.cdx.json
- Un projet par application, une version par livrable promu
- Une notification (webhook, messagerie) sur
NEW_VULNERABILITY alerte quand une CVE touche une version en production - Prévoir plusieurs gigaoctets de RAM pour son serveur d'API : instance partagée ou option
VEX : dire si l'on est vraiment affecté
- VEX (Vulnerability Exploitability eXchange) : déclaration, pour une CVE et un produit, de l'exploitabilité réelle
- Statuts :
not_affected, affected, fixed, under_investigation - Un
not_affected porte une justification normalisée : component_not_present vulnerable_code_not_present vulnerable_code_not_in_execute_path vulnerable_code_cannot_be_controlled_by_adversary inline_mitigations_already_exist - Formats : OpenVEX, CycloneDX VEX, CSAF
Un document OpenVEX
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://securepay.local/vex/2026-001",
"author": "SecurePay Security",
"timestamp": "2026-11-02T00:00:00Z",
"version": 1,
"statements": [{
"vulnerability": { "name": "CVE-2021-22945" },
"products": [{ "@id": "pkg:deb/debian/[email protected]%2Bdeb11u1?arch=amd64&distro=debian-11.3" }],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"impact_statement": "La fonction vulnérable n'est jamais appelée par SecurePay"
}]
}
Appliquer le VEX dans la CI
trivy image --vex vex/securepay.openvex.json --show-suppressed \
--severity HIGH,CRITICAL --exit-code 1 "$IMAGE@$DIGEST"
- La CVE déclarée
not_affected ne fait plus échouer le job --show-suppressed la conserve dans le rapport, avec le statut, la justification et le fichier source - Le fichier VEX est versionné, revu par MR et signé comme le reste : c'est une décision de sécurité
- Diffusé avec le SBOM, il évite aussi à vos clients de traiter des alertes non pertinentes
Piloter
Les indicateurs
| Indicateur | Ce qu'il révèle |
| Délai moyen de remédiation par sévérité | capacité à corriger dans les temps |
| Constats hors SLA | dette de sécurité visible |
| Évolution du backlog | le programme progresse-t-il ? |
| Taux de faux positifs par outil | réglage des scanners à revoir |
| Couverture | part des dépôts et des images réellement scannés |
| Acceptations expirées | risques acceptés sans réexamen |
- Le nombre de scanners ou de règles n'est pas un indicateur de sécurité
La gouvernance
- Triage hebdomadaire : les nouveaux constats critiques et hauts sont qualifiés dans la semaine
- Rôles clairs : qui qualifie, qui corrige, qui accepte un risque
- Revue mensuelle : acceptations expirées, constats hors SLA, faux positifs récurrents
- Reporting PSSI : les indicateurs alimentent le comité sécurité et le dossier d'audit
- Amélioration continue : un faux positif récurrent fait évoluer la règle du scanner
Anti-patterns à proscrire
- Empiler les scanners sans plateforme ni processus de triage
import-scan à chaque pipeline : le backlog grossit de doublons - Supprimer un constat gênant au lieu de le qualifier
- Des acceptations de risque sans date d'expiration
- Prioriser au seul score CVSS
- Un jeton d'API administrateur dans les variables de la CI
À retenir
- Un programme de gestion des vulnérabilités centralise, déduplique, priorise et suit chaque constat jusqu'à sa clôture
- La priorité combine sévérité, probabilité d'exploitation (EPSS, KEV) et contexte d'exposition
- En CI, on réimporte : pas de doublons, et les constats corrigés se ferment seuls
- Toute exception est tracée, justifiée et bornée dans le temps
- Les SBOM se surveillent dans la durée, et le VEX déclare ce qui n'est pas exploitable
Pour aller plus loin