Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

SBOM : l'inventaire de ce qu'on livre, mesuré avec Syft

Par mis à jour le

Améliorer cette page

Un SBOM (Software Bill of Materials) est l'inventaire lisible par une machine de ce que contient un logiciel : paquets système, bibliothèques, dépendances transitives, versions, licences. Il sert le jour où une CVE critique tombe et que la question devient « quels artefacts livrés embarquent ce composant ? ». Cette leçon s'adresse à un DevOps qui doit produire ce document en CI, le vérifier et le distribuer avec l'image.

Tout est mesuré sur un registre local : les sorties de Syft avec la 1.54.1 le 14 octobre 2026 (mêmes chiffres qu'avec la 1.52.0 deux semaines plus tôt), celles de Grype 0.119.0 et de Cosign v3.1.3 le 1er octobre. Trois chiffres résument la leçon : 4 composants pour un requirements.txt, 96 pour l'image python:3.13-slim, et 0 empreinte au niveau des paquets dans les deux cas. Un SBOM n'est pas exhaustif par nature : sa couverture dépend de ce qu'on scanne.

  • Distinguer les deux formats normalisés, et savoir lequel votre outil écrit réellement, qui n'est pas toujours la dernière version publiée.
  • Générer un SBOM avec Syft depuis l'artefact que vous livrez, épinglé par empreinte.
  • Mesurer la couverture de votre SBOM face aux dix-sept champs exigés en 2026, plutôt que de la supposer.
  • Exploiter l'inventaire pour répondre à une CVE avec jq et Grype.
  • Distribuer le SBOM en attestation signée attachée à l'image, et la vérifier.
  • Prouver les exigences SOCLE-PKG-GEN-1 et SOCLE-PKG-SBM-1 à -3 du référentiel Socle DevSecOps, dont la première impose un SBOM par artefact et la deuxième qu'il porte licences et empreintes.

Un SBOM est un document structuré qui décrit un artefact précis, une image ou un binaire, et répond à la question « qu'y a-t-il dedans ? ». Il ne se lit pas à la main : il s'interroge, se compare et se scanne. Les informations qu'il porte tiennent en quatre familles :

  • les composants : nom, version, producteur quand il est connu ;
  • des identifiants stables, surtout le purl (Package URL, comme pkg:deb/debian/openssl@3.5.6-1~deb13u2), parfois un CPE ;
  • les relations de dépendance, directes et transitives ;
  • des métadonnées : licences, empreintes, emplacement dans l'image.

Le cycle de vie qui donne sa valeur au document tient en quatre étapes : on le génère au build, on le distribue avec l'image, on le scanne en continu, et on réagit quand une vulnérabilité touche un composant listé.

Cycle de vie d'un SBOM en quatre étapes : générer avec syft scan sur l'image, distribuer en attestation signée, scanner avec Grype ou Dependency-Track, réagir en cherchant, priorisant et corrigeant, puis régénérer au build suivant.Générersyft scan sur l'imageDistribuerattestation signéeScannerGrype, Dependency-TrackRéagirchercher, prioriser, corriger
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Le SBOM est souvent confondu avec les documents qui l'entourent dans la chaîne d'approvisionnement. Il ne fait qu'inventorier : chaque autre garantie vient d'un outil ou d'un document distinct, vus dans ce module.

  • Ce n'est pas un scan de vulnérabilités : Grype ou Trivy le lisent pour en produire un.
  • Ce n'est pas une preuve d'intégrité : c'est le rôle de la signature et de l'attestation.
  • Ce n'est pas un verdict d'exploitabilité : c'est le rôle du VEX, vu dans la leçon suivante.
  • Ce n'est pas un inventaire exhaustif : sa couverture dépend de la source scannée, de l'outil et du moment de la génération, comme le montrent les mesures ci-dessous.

Que demandent les « Minimum Elements » de 2026 ?

Section intitulée « Que demandent les « Minimum Elements » de 2026 ? »

Le document de référence a changé de nom, de version et d'auteurs le 29 juillet 2026. Ce qu'on citait sous « NTIA 2021 » est désormais les 2026 Minimum Elements for a Software Bill of Materials, en version 2.1, publié par la CISA avec la NSA, le FBI et quinze partenaires internationaux, dont l'ANSSI pour la France.

Son historique tient en trois lignes, et il évite de citer un brouillon pour une norme. La version 2.0 n'a jamais été finale : elle a servi de base à l'appel à commentaires de 2025.

VersionDateCe que c'est
1.012 juillet 2021les minimum elements de la NTIA
2.022 août 2025un brouillon soumis à commentaires
2.129 juillet 2026la version finale, celle qu'on cite

Le document définit dix-sept champs de données, contre sept en 2021. Les nouveaux champs portent sur la licence, l'empreinte des composants, la signature de l'auteur et le contexte de génération :

ChampCe qu'il porte
Component Name, Component Versionle composant et sa version
Component Producerqui le produit
Component Licensenouveau : sous quelle licence
Component Identifierspurl, CPE, clés de recherche
Component Hash Algorithm, Component Hash Valuenouveaux : l'empreinte, et l'algorithme qui l'a produite
Component Dependency Relationshipqui dépend de qui
SBOM Author, SBOM Author Signaturequi a produit le SBOM, et sa signature
SBOM Data Format Name, SBOM Data Format Versionle format et sa version
SBOM Generation Contextnouveau : à quelle phase du cycle de vie
SBOM Timestamp, SBOM Versionquand, et quelle révision
SBOM Tool Name, SBOM Tool Versionavec quoi

Un changement compte plus que les autres : l'élément Depth de 2021 est remplacé par Coverage. La justification de l'annexe B du document décrit exactement le piège des mesures suivantes : « The Depth element was previously defined as capturing software component information for top-level dependencies only. This definition reflected the capabilities of SBOM tooling at the time rather than the depth of information needed to make informed security decisions. »

Combien de ces dix-sept champs votre SBOM porte-t-il vraiment ?

Section intitulée « Combien de ces dix-sept champs votre SBOM porte-t-il vraiment ? »

Un SBOM généré depuis un requirements.txt en couvre neuf sur dix-sept. Mesuré avec Syft 1.54.1 sur un fichier de quatre dépendances épinglées (flask 3.1.2, requests 2.32.5, pyyaml 6.0.3, gunicorn 23.0.0), en CycloneDX : la licence, l'empreinte et le producteur sont absents des quatre composants, et aucune relation de dépendance n'est déclarée.

PrésentsAbsents
Name, Version, Identifiers (purl)Producer, License
Data Format Name et VersionHash Algorithm, Hash Value
Timestamp, Tool Name, Tool Version, SBOM VersionDependency Relationship, Author, Author Signature, Generation Context

Ce n'est pas un défaut de l'outil : un fichier de déclarations ne porte ni licence, ni empreinte. Syft ne peut pas inventer ce que la source ne contient pas. Les trois champs d'auteur, de signature et de contexte ne viennent jamais d'un scanner : c'est au pipeline de les ajouter, la signature par une attestation.

La couverture dépend de ce que vous scannez, pas de la commande

Section intitulée « La couverture dépend de ce que vous scannez, pas de la commande »

La démonstration tient en trois lignes : même outil, même format de sortie, trois sources différentes. Les pourcentages comptent les composants logiciels (paquets et bibliothèques), sans les entrées de type fichier que Syft ajoute pour une image.

Source scannée par syft scanComposantsLicenceEmpreinte du composantProducteur
file:requirements.txt40 %0 %0 %
les mêmes paquets installés (pip install --target)1593 %0 %60 %
l'image python:3.13-slim9692 %0 %92 %

De 4 à 96 composants selon ce qu'on pointe. Le fichier de déclarations ne voit que les dépendances directes ; l'environnement installé révèle les transitives (jinja2, werkzeug, urllib3…) et leurs licences ; l'image ajoute les paquets Debian et l'interpréteur. Un SBOM produit depuis le dépôt décrit ce que le projet demande, un SBOM produit depuis l'image décrit ce qu'il contient : c'est pour cela que SBOM Generation Context est devenu un champ obligatoire.

La colonne des empreintes mérite un second regard. Dans une image, Syft calcule bien des empreintes, mais sur les 2 651 fichiers qu'il liste comme composants de type file, pas sur les paquets eux-mêmes. Un auditeur qui cherche Component Hash Value sur openssl ne la trouvera pas. La conséquence pratique reste nette : générez le SBOM depuis l'artefact que vous livrez, et vérifiez les champs exigés au lieu de les supposer.

Le SBOM change la question qu'on se pose pendant un incident. Sans lui, on cherche où un composant pourrait se trouver ; avec lui, on interroge un inventaire déjà constitué. Les grands incidents de la chaîne d'approvisionnement, Log4Shell en 2021 ou XZ Utils en 2024, ont montré le coût de la première approche.

Quand une CVE critique tombe, la première question est toujours « est-ce qu'on est touchés ? ». Sans inventaire centralisé, la réponse demande de fouiller chaque package.json, requirements.txt ou go.mod, de rescanner chaque image une par une et d'interroger chaque équipe. Le résultat prend des heures ou des jours, pendant que la vulnérabilité reste exploitable, et sans certitude d'avoir tout couvert. La leçon d'ouverture du module, sécurité de la supply chain logicielle, détaille ces vecteurs d'attaque.

Avec un SBOM par artefact, conservé à côté de l'image, la même question devient une requête sur des données structurées. La commande suivante, jouée sur le SBOM de python:3.13-slim, liste en une ligne toutes les variantes d'OpenSSL présentes, avec leur purl :

Fenêtre de terminal
jq -r '.components[]
| select(.type != "file")
| select(.name | test("^(openssl|libssl)"))
| "\(.name) \(.version)"' python-3.13-slim.cdx.json
# libssl3t64 3.5.6-1~deb13u2
# openssl 3.5.6-1~deb13u2
# openssl-provider-legacy 3.5.6-1~deb13u2

Le filtre select(.type != "file") écarte les entrées de fichiers qui, sinon, noieraient le résultat. Sur un répertoire de SBOM, une boucle for sur les fichiers *.cdx.json pose la même question à tout le parc, sans rescanner une seule image.

Deux formats dominent : CycloneDX et SPDX. Les deux sont des normes publiées, lisibles par tous les outils courants, et Syft écrit les deux. Leur différence pratique tient moins au contenu qu'à la version que votre outil produit par défaut, et c'est elle qu'il faut vérifier.

CycloneDX est un standard porté par l'OWASP, conçu dès le départ pour la sécurité applicative. Il est normalisé par l'Ecma sous le nom ECMA-424 : la première édition, en juin 2024, correspond à CycloneDX 1.6, la deuxième, en décembre 2025, à CycloneDX 1.7, publiée par l'OWASP le 21 octobre 2025.

  • CycloneDX 1.4 (2022) : ajout du VEX, pour qualifier l'exploitabilité d'une vulnérabilité ;
  • CycloneDX 1.5 (2023) : formulation (comment l'artefact a été construit) et inventaire des modèles d'apprentissage automatique ;
  • CycloneDX 1.6 (2024) : inventaire cryptographique (CBOM) et attestations ;
  • CycloneDX 1.7 (2025) : version courante.

Syft 1.54.1 écrit du CycloneDX 1.7 par défaut. Le suffixe @version force une version plus ancienne quand l'outil qui consomme le SBOM l'exige. Mesuré : les versions 1.2 à 1.7 sont acceptées, et @2.0 est refusé avec la liste des formats connus, ce qui est cohérent avec une 2.0 non publiée.

Fenêtre de terminal
# Registre local servi en HTTP : SYFT_REGISTRY_INSECURE_USE_HTTP=true
IMAGE="registry:localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06"
# CycloneDX 1.7 par défaut
syft scan "$IMAGE" -o cyclonedx-json > sbom.cdx.json
jq -r .specVersion sbom.cdx.json
# 1.7
# Forcer une version plus ancienne
syft scan "$IMAGE" -o cyclonedx-json@1.5 > sbom-1.5.cdx.json

L'ancienne commande syft packages fonctionne encore, mais Syft 1.54.1 affiche l'avertissement de dépréciation ci-dessous : les exemples qui circulent avec syft packages sont à mettre à jour.

Command "packages" is deprecated, use `syft scan` instead

SPDX (Software Package Data Exchange) est un standard de la Linux Foundation, normalisé sous ISO/IEC 5962:2021 (qui correspond à SPDX 2.2.1). Il est historiquement fort sur la conformité des licences : sa liste d'identifiants (MIT, Apache-2.0, GPL-3.0-only) est reprise par CycloneDX lui-même.

  • SPDX 2.3 (2022) : la version qu'écrit Syft par défaut ;
  • SPDX 3.0 (2024) : refonte en profils (Core, Software, Security, Licensing, Build, AI, Dataset), avec des relations VEX dans le profil Security.

La version courante de la spécification n'est pas celle que l'outil produit. Mesuré avec Syft 1.54.1 : spdx-json sans suffixe écrit du SPDX-2.3, et il faut demander spdx-json@3.0 pour obtenir un document SPDX 3, dont le contexte JSON-LD pointe vers la 3.0.1. C'est l'inverse de CycloneDX, où le défaut suit la dernière version.

Fenêtre de terminal
syft scan "$IMAGE" -o spdx-json > sbom.spdx.json
jq -r .spdxVersion sbom.spdx.json
# SPDX-2.3
syft scan "$IMAGE" -o spdx-json@3.0 > sbom.spdx3.json
jq -r '."@context"' sbom.spdx3.json
# https://spdx.org/rdf/3.0.1/spdx-context.jsonld

Le tableau résume les points qui décident d'un choix. Les deux lignes de version sont celles qu'on oublie : la version de la spécification et la version que votre outil écrit sont deux choses différentes, et l'écart est réel côté SPDX.

CritèreCycloneDXSPDX
OrganismeOWASP, normalisé par l'EcmaLinux Foundation, normalisé par l'ISO
Version actuelle de la spécification1.7 (octobre 2025)3.0.1
Version écrite par défaut par Syft 1.54.11.72.3
Norme publiéeECMA-424 (1re édition juin 2024, 2e décembre 2025)ISO/IEC 5962:2021
Focus d'origineSécurité, supply chainLicences, conformité
VEXIntégré depuis 1.4Relations VEX en 3.0

Ma recommandation : produisez au moins le format qu'attendent vos consommateurs, et vérifiez sa version avec jq avant de le publier. Les deux se génèrent depuis le même artefact en deux commandes, ce qui évite de choisir quand un client exige SPDX et que vos outils lisent CycloneDX.

Syft, d'Anchore, est l'outil de référence de cette leçon, mais il n'est pas le seul. Le choix dépend de ce que vous scannez : une image ou un binaire se prêtent bien à Syft et Trivy, un projet source multi-langages à cdxgen. Le guide dédié à Syft détaille ses sources et ses options.

OutilÉditeurPoints fortsFormats
SyftAnchoreImages, archives, systèmes de fichiersCycloneDX, SPDX
TrivyAqua SecurityScanner de vulnérabilités avec génération de SBOMCycloneDX, SPDX
cdxgenOWASP CycloneDXProjets source multi-langagesCycloneDX

L'ancien spdx-sbom-generator du projet SPDX est archivé sur GitHub : ne le prenez plus comme point de départ. Côté analyse, trois outils lisent un SBOM existant :

OutilFonctionGuide
GrypeScan de vulnérabilités d'un SBOMGuide Grype
TrivyScan multi-cibles, SBOM comprisGuide Trivy
Dependency-TrackSuivi continu d'un parc de SBOMGuide Dependency-Track

Grype lit un SBOM avec le préfixe sbom: et le confronte à sa base de vulnérabilités, sans rescanner l'image. Mesuré avec Grype 0.119.0 sur le SBOM de python:3.13-slim : 335 correspondances, dont 176 avec un correctif publié. L'option --fail-on high fait sortir la commande en code 2, ce qui suffit à bloquer un job CI.

Fenêtre de terminal
grype sbom:./sbom.cdx.json
# 335 lignes, dont openssl 3.5.6-1~deb13u2, corrigé en 3.5.7-1~deb13u2
grype sbom:./sbom.cdx.json --only-fixed --fail-on high
echo $?
# 2

L'option --only-fixed retire les vulnérabilités sans correctif publié, sur lesquelles l'équipe ne peut pas agir tout de suite. Le même SBOM rescanné un mois après donne un autre résultat : la base évolue, l'inventaire reste fixe, et c'est précisément ce qui permet de rescanner un parc entier sans reconstruire une image.

Dependency-Track est une plateforme qui ingère les SBOM, les corrèle en continu avec les bases de vulnérabilités et alerte quand une nouvelle CVE touche un composant déjà livré. Son API attend le SBOM en multipart, pas en JSON brut : un curl -d @sbom.cdx.json avec un en-tête JSON, encore courant dans les exemples, ne correspond pas à l'API documentée.

Fenêtre de terminal
# Envoi d'un SBOM, projet créé à la volée s'il n'existe pas
curl -X POST "https://dtrack.interne.exemple/api/v1/bom" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-F "autoCreate=true" \
-F "projectName=order-service" \
-F "projectVersion=2.1.0" \
-F "bom=@sbom.cdx.json"

La forme PUT existe aussi, avec le SBOM encodé en base64 dans un corps JSON. Les deux formes sont décrites dans la documentation CI/CD de Dependency-Track. La clé d'API vient d'un secret du pipeline, jamais du code.

Un SBOM qui reste sur le poste du développeur, ou dans un artefact CI expiré, ne sert à rien le jour de l'incident. Pour être utile, il doit être accessible aux équipes et aux clients, associé à l'artefact exact qu'il décrit, et vérifiable : on doit pouvoir prouver qu'il n'a pas été modifié après sa génération.

Trois stratégies se rencontrent, de la plus simple à la plus robuste. Le schéma montre ce qui les sépare : seules les deux dernières placent le SBOM dans le registre, à côté de l'image désignée par son digest, et seule la troisième le signe.

Trois façons de distribuer un SBOM généré au build : un fichier à côté, en artefact CI ou en release, détaché du registre ; un référent OCI attaché par oras attach, non signé ; une attestation signée par cosign attest. Les deux dernières rejoignent le registre OCI où l'image est désignée par digest.SBOM généré au buildFichier à côtéartefact CI, releaseRéférent OCIoras attach, non signéAttestation signéecosign attestRegistre OCIimage par digest
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %
StratégieAvantagesInconvénients
Fichier à côté (CI, release)Simple à mettre en placeDissocié de l'image, risque de désynchronisation
Référent OCI (oras attach)Dans le registre, lié au digestNon signé : rien ne prouve qui l'a produit
Attestation signée (cosign attest)Intégrité et origine vérifiablesDemande une clé ou une identité OIDC

La commande cosign attach sbom, longtemps citée pour la deuxième stratégie, est dépréciée : Cosign v3.1.3 l'accepte encore mais affiche « SBOM attachments are deprecated and support will be removed », et renvoie vers les attestations. Pour un SBOM non signé dans le registre, oras fait le même travail avec le mécanisme standard des référents OCI :

Fenêtre de terminal
oras attach --plain-http --artifact-type application/vnd.cyclonedx+json \
localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06 \
sbom.cdx.json:application/vnd.cyclonedx+json
oras discover --plain-http localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06

Mesuré avec oras 1.3.4 sur un registre local registry:3 servi en HTTP, d'où l'option --plain-http : oras discover affiche le SBOM sous l'image, à côté des signatures que Cosign v3 range au même endroit.

L'attestation va plus loin : Cosign enveloppe le SBOM dans une déclaration in-toto dont le sujet est le digest de l'image, puis la signe. Modifier le SBOM casse la signature, et un SBOM attesté pour une autre image ne passe pas la vérification. La signature keyless exige une identité OIDC ; l'exemple ci-dessous utilise une paire de clés, et une configuration de signature sans journal de transparence, pour rester sur un registre local sans rien publier sur l'instance publique de Sigstore.

Fenêtre de terminal
# Configuration de signature vide : aucun service public sollicité
cosign signing-config create --out signing-config.json
# Attester le SBOM CycloneDX sur l'image désignée par digest
cosign attest --key cosign.key --signing-config signing-config.json \
--type cyclonedx --predicate sbom.cdx.json --allow-insecure-registry \
localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06
# Vérifier : la clé publique ET le type de prédicat
cosign verify-attestation --key cosign.pub --type cyclonedx \
--insecure-ignore-tlog=true --allow-insecure-registry \
localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06

Trois résultats mesurés méritent d'être retenus. La vérification réussie renvoie la déclaration signée, dont le predicateType vaut https://cyclonedx.org/bom et le sujet le digest exact de l'image. Sans --key ni identité, cosign verify-attestation échoue avec « --certificate-identity or --certificate-identity-regexp is required » : il n'existe pas de vérification « par défaut ». Et un --type spdxjson sur une image qui ne porte qu'un SBOM CycloneDX échoue avec « none of the attestations matched the predicate type ».

L'option --insecure-ignore-tlog=true n'est justifiée ici que parce qu'aucun journal de transparence n'a été utilisé, et --allow-insecure-registry que parce que le registre de test répond en HTTP. En production, la signature passe par Rekor et la vérification le consulte, comme le détaille la leçon sur Cosign.

Pourquoi attester plutôt que déposer un fichier ?

Section intitulée « Pourquoi attester plutôt que déposer un fichier ? »

Parce qu'on construit un graphe d'artefacts vérifiable autour de l'image : SBOM, signature et provenance SLSA sont rangés au même endroit, liés au même digest, et signés par la même chaîne de build. Le jour où un client demande « prouvez-moi ce que contient cette image », la réponse est une commande de vérification, pas une recherche dans les artefacts CI. C'est aussi ce qu'exige SOCLE-PKG-SBM-2 : un SBOM attaché à l'artefact et récupérable par ses consommateurs.

Une CVE critique qui tombe un vendredi soir est le cas d'usage qui justifie tout le reste. Avec des SBOM centralisés, la réponse suit quatre étapes qui s'outillent chacune, du simple jq à la plateforme de suivi. L'exemple historique reste Log4Shell (CVE-2021-44228, score CVSS 10.0), qui touchait log4j-core de la version 2.0-beta9 à la 2.14.1.

La première question est quels artefacts embarquent le composant. Une boucle sur les SBOM conservés y répond, avec la version et le purl, qui désigne sans ambiguïté le paquet dans son écosystème. Pour la mesure, un dossier sboms/ contient deux SBOM : celui de python:3.13-slim et celui d'un service Java qui embarque le JAR officiel log4j-core-2.14.1.jar de Maven Central.

Fenêtre de terminal
for sbom in sboms/*.cdx.json; do
jq -r --arg f "$sbom" '.components[]
| select(.name == "log4j-core")
| "\($f) \(.version) \(.purl)"' "$sbom"
done
# sboms/billing-api.cdx.json 2.14.1 pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1

Seul le service Java ressort : Syft a reconnu le JAR et lui a attribué le purl Maven exact, sans avoir besoin du pom.xml du projet.

Le purl est particulièrement utile : c'est la clé que les bases OSV et GitHub Advisory emploient pour désigner un paquet, ce qui permet une corrélation directe sans deviner le nom.

Étape 2 : vérifier si la version est vulnérable

Section intitulée « Étape 2 : vérifier si la version est vulnérable »

Une version trouvée n'est pas forcément une version vulnérable. Plutôt que de comparer des numéros à la main, on laisse Grype confronter le SBOM à sa base : il connaît les plages affectées et les versions corrigées, y compris les correctifs rétroportés par les distributions, qu'une comparaison alphabétique ne voit pas.

Fenêtre de terminal
$ grype sbom:sboms/billing-api.cdx.json --only-fixed -q
NAME INSTALLED FIXED IN TYPE VULNERABILITY SEVERITY EPSS RISK
log4j-core 2.14.1 2.15.0 java-archive GHSA-jfh8-c2jp-5v3q Critical 100.0% (100th) 100.0 (kev)
log4j-core 2.14.1 2.16.0 java-archive GHSA-7rjr-3q55-vv33 Critical 100.0% (99th) 99.0 (kev)
log4j-core 2.14.1 2.17.0 java-archive GHSA-p6xc-xr62-6r2g High 100.0% (99th) 80.5
log4j-core 2.14.1 2.17.1 java-archive GHSA-8489-44mv-ggj8 Medium 97.9% (99th) 56.8
...

Mesuré avec Grype 0.119.0 : 7 avis sur ce seul JAR. Le premier, GHSA-jfh8-c2jp-5v3q, est l'avis GitHub de Log4Shell, corrigé en 2.15.0 et marqué (kev) : il figure au catalogue des vulnérabilités activement exploitées de la CISA. La colonne FIXED IN donne directement la version cible de la montée.

Tous les artefacts concernés ne se valent pas. On priorise selon l'exposition, la criticité métier et l'exploitabilité, avec les critères du guide CVE, CVSS et EPSS. Les colonnes EPSS et RISK de Grype 0.119.0, et le marqueur (kev), donnent déjà une première probabilité d'exploitation à croiser avec le contexte.

CritèrePriorité hautePriorité basse
ExpositionProduction exposée à InternetEnvironnement de développement interne
Criticité métierService critique 24/7Traitement mensuel
ExploitabilitéExploit public, EPSS élevéVulnérabilité théorique
Effort de correctionMontée de version simpleRefonte importante

À l'échelle d'un parc, la boucle jq ne suffit plus. Dependency-Track garde chaque SBOM envoyé par la CI, réévalue le parc à chaque mise à jour de ses sources de vulnérabilités, et alerte quand une nouvelle CVE touche un composant déjà livré. Le temps de réponse passe alors de plusieurs jours de recherche à une requête sur la plateforme.

Un scan sur un SBOM complet remonte des centaines de correspondances : 335 sur la seule image python:3.13-slim. Beaucoup ne sont pas exploitables dans votre contexte : code vulnérable jamais appelé, fonction désactivée, condition d'exploitation absente. Sans moyen de le documenter, les équipes trient le même bruit à chaque scan, jusqu'à ignorer les vraies alertes : c'est l'alert fatigue.

Le VEX (Vulnerability Exploitability eXchange) répond à ce problème : un document qui associe une vulnérabilité à un produit et à un statut (not_affected, affected, fixed, under_investigation), avec une justification. Grype et Trivy savent l'appliquer pour filtrer leur rapport. Il existe en trois formats, OpenVEX, CycloneDX VEX et CSAF VEX, et fait l'objet de la leçon suivante, mesures comprises.

Ce lab vient du fil rouge de la formation Python : l'outil security_check.py, construit lab après lab, apprend à lire un SBOM CycloneDX réel, produit par syft. Comme un SBOM liste des composants et non des failles, l'outil croise chaque composant PyPI, lu dans son purl, avec la base OSV, et fait de chaque vulnérabilité connue un finding, avec la sévérité de son avis GitHub. La validation vérifie les requêtes envoyées à une API OSV factice, le résumé par sévérité, et le seuil qui arrête un pipeline.

  • Un SBOM n'est pas un inventaire exhaustif : sa couverture dépend de la source scannée, de l'outil et du moment. Le document de 2026 a remplacé l'élément Depth par Coverage pour cette raison précise.
  • De 4 à 96 composants selon ce qu'on pointe, avec Syft 1.54.1 : générez le SBOM depuis l'artefact livré, désigné par son digest, pas depuis le dépôt de code.
  • Le document de référence est les 2026 Minimum Elements, version 2.1 du 29 juillet 2026, co-signé par l'ANSSI, avec dix-sept champs au lieu de sept.
  • La version de la spécification n'est pas celle que l'outil écrit. Syft 1.54.1 produit du CycloneDX 1.7 mais du SPDX 2.3. Vérifiez la sortie avec jq, ne la supposez pas.
  • CycloneDX est une norme publiée depuis juin 2024 (ECMA-424), dont la deuxième édition de décembre 2025 couvre la 1.7.
  • syft packages et cosign attach sbom sont dépréciés : on écrit syft scan, et on distribue en attestation avec cosign attest.
  • La preuve attendue par SOCLE-PKG-SBM-1 et SBM-2 est un SBOM complet par artefact (composants, licences, empreintes), au format normalisé, attaché à l'artefact et conservé, récupérable par les consommateurs.

Vérifiez que l'essentiel de cette leçon est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn