Créer une exception en utilisant VEX
Vulnerability Exploitability eXchange (VEX) est un format standard pour documenter les vulnérabilités dans le contexte d'un paquet logiciel ou d'un produit. Docker Scout prend en charge les documents VEX pour créer des exceptions pour les vulnérabilités dans les images.
NoteVous pouvez aussi créer des exceptions en utilisant le tableau de bord Docker Scout ou Docker Desktop. L'interface graphique fournit une interface conviviale pour créer des exceptions, et il est facile de gérer les exceptions pour plusieurs images. Elle vous permet aussi de créer des exceptions pour plusieurs images, ou toute votre organisation, d'un seul coup. Pour plus d'informations, voir Créer une exception en utilisant l'interface graphique.
Prérequis
Pour créer des exceptions en utilisant des documents OpenVEX, vous avez besoin de :
- La dernière version de Docker Desktop ou du plugin CLI Docker Scout
- L'outil de ligne de commande
vexctl
. - Le stockage d'image containerd doit être activé
- Permissions d'écriture sur le dépôt de registre où l'image est stockée
Introduction à VEX
Le standard VEX est défini par un groupe de travail de l'Agence de cybersécurité et de sécurité des infrastructures des États-Unis (CISA). Au cœur de VEX se trouvent les évaluations d'exploitabilité. Ces évaluations décrivent le statut d'un CVE donné pour un produit. Les statuts de vulnérabilité possibles dans VEX sont :
- Non affecté : Aucune remédiation n'est requise concernant cette vulnérabilité.
- Affecté : Des actions sont recommandées pour remédier ou traiter cette vulnérabilité.
- Corrigé : Ces versions de produit contiennent un correctif pour la vulnérabilité.
- En cours d'investigation : Il n'est pas encore connu si ces versions de produit sont affectées par la vulnérabilité. Une mise à jour sera fournie dans une version ultérieure.
Il existe plusieurs implémentations et formats de VEX. Docker Scout prend en charge l'implémentation OpenVex. Indépendamment de l'implémentation spécifique, l'idée centrale est la même : fournir un cadre pour décrire l'impact des vulnérabilités. Les composants clés de VEX indépendamment de l'implémentation incluent :
- Document VEX
- Un type d'avis de sécurité pour stocker les déclarations VEX. Le format du document dépend de l'implémentation spécifique.
- Déclaration VEX
- Décrit le statut d'une vulnérabilité dans un produit, si elle est exploitable, et s'il existe des moyens de remédier au problème.
- Justification et impact
- Selon le statut de vulnérabilité, les déclarations incluent une justification ou une déclaration d'impact décrivant pourquoi un produit est ou n'est pas affecté.
- Déclarations d'action
- Décrivent comment remédier ou atténuer la vulnérabilité.
Exemple vexctl
La commande d'exemple suivante crée un document VEX déclarant que :
- Le produit logiciel décrit par ce document VEX est l'image Docker
example/app:v1
- L'image contient le paquet npm
[email protected]
- Le paquet npm est affecté par une vulnérabilité connue :
CVE-2022-24999
- L'image n'est pas affectée par le CVE, car le code vulnérable n'est jamais exécuté dans les conteneurs qui exécutent cette image
$ vexctl create \
--author="[email protected]" \
--product="pkg:docker/example/app@v1" \
--subcomponents="pkg:npm/[email protected]" \
--vuln="CVE-2022-24999" \
--status="not_affected" \
--justification="vulnerable_code_not_in_execute_path" \
--file="CVE-2022-24999.vex.json"
Voici une description des options dans cet exemple :
--author
- L'email de l'auteur du document VEX.
--product
- URL de paquet (PURL) de l'image Docker. Un PURL est un identifiant
pour l'image dans un format standardisé, défini dans la
spécification PURL.
Les chaînes PURL d'image Docker commencent par un préfixe de type
pkg:docker
, suivi par le dépôt d'image et la version (le tag d'image ou le digest SHA256). Contrairement aux tags d'image, où la version est spécifiée commeexample/app:v1
, dans PURL le dépôt d'image et la version sont séparés par un@
. --subcomponents
- PURL du paquet vulnérable dans l'image. Dans cet exemple, la
vulnérabilité existe dans un paquet npm, donc le PURL
--subcomponents
est l'identifiant pour le nom et la version du paquet npm (pkg:npm/[email protected]
).Si la même vulnérabilité existe dans plusieurs paquets,
vexctl
vous permet de spécifier le flag--subcomponents
plusieurs fois pour une seule commandecreate
.Vous pouvez aussi omettre
--subcomponents
, auquel cas la déclaration VEX s'applique à toute l'image. --vuln
- ID du CVE que la déclaration VEX traite.
--status
- C'est le label de statut de la vulnérabilité. Ceci décrit la
relation entre le logiciel (
--product
) et le CVE (--vuln
). Les valeurs possibles pour le label de statut dans OpenVEX sont :not_affected
affected
fixed
under_investigation
Dans cet exemple, la déclaration VEX affirme que l'image Docker n'est pas affectée (
not_affected
) par la vulnérabilité. Le statutnot_affected
est le seul statut qui résulte en suppression de CVE, où le CVE est filtré hors des résultats d'analyse. Les autres statuts sont utiles à des fins de documentation, mais ils ne fonctionnent pas pour créer des exceptions. Pour plus d'informations sur tous les labels de statut possibles, voir Labels de statut dans la spécification OpenVEX. --justification
- Justifie le label de statut
not_affected
, informant pourquoi le produit n'est pas affecté par la vulnérabilité. Dans ce cas, la justification donnée estvulnerable_code_not_in_execute_path
, signalant que la vulnérabilité ne peut pas être exécutée telle qu'utilisée par le produit.Dans OpenVEX, les justifications de statut peuvent avoir une des cinq valeurs possibles :
component_not_present
vulnerable_code_not_present
vulnerable_code_not_in_execute_path
vulnerable_code_cannot_be_controlled_by_adversary
inline_mitigations_already_exist
Pour plus d'informations sur ces valeurs et leurs définitions, voir Justifications de statut dans la spécification OpenVEX.
--file
- Nom de fichier de la sortie du document VEX
Exemple de document JSON
Voici le JSON OpenVEX généré par cette commande :
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-749f79b50f5f2f0f07747c2de9f1239b37c2bda663579f87a35e5f0fdfc13de5",
"author": "[email protected]",
"timestamp": "2024-05-27T13:20:22.395824+02:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2022-24999"
},
"timestamp": "2024-05-27T13:20:22.395829+02:00",
"products": [
{
"@id": "pkg:docker/example/app@v1",
"subcomponents": [
{
"@id": "pkg:npm/[email protected]"
}
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}
Comprendre comment les documents VEX sont supposés être structurés peut être un peu complexe. La spécification OpenVEX décrit le format et toutes les propriétés possibles des documents et déclarations. Pour tous les détails, référez-vous à la spécification pour en savoir plus sur les champs disponibles et comment créer un document OpenVEX bien formé.
Pour en savoir plus sur les flags disponibles et la syntaxe de l'outil CLI vexctl
et
comment l'installer, référez-vous au dépôt GitHub vexctl
.
Vérification des documents VEX
Pour tester si les documents VEX que vous créez sont bien formés et produisent les
résultats attendus, utilisez la commande docker scout cves
avec le flag --vex-location
pour appliquer un document VEX à une analyse d'image locale à l'aide de la CLI.
La commande suivante invoque une analyse d'image locale qui intègre tous les documents VEX
dans le répertoire spécifié, en utilisant le flag --vex-location
. Dans cet exemple, la CLI
est instruite de rechercher des documents VEX dans le répertoire de travail actuel.
$ docker scout cves <IMAGE> --vex-location .
Le résultat de la commande docker scout cves
affiche les résultats avec toutes les déclarations VEX
trouvées sous le flag --vex-location
. Par exemple, les CVE affectées sont filtrées hors des
résultats. Si le résultat ne semble pas prendre en compte les déclarations VEX, c'est une indication
que les documents VEX peuvent être invalides de quelque manière que ce soit.
Les choses à surveiller incluent :
- Le PURL d'une image Docker doit commencer par
pkg:docker/
suivi du nom de l'image. - Dans un PURL d'image Docker, le nom de l'image et sa version sont séparés par
@
. Une image nomméeexample/myapp:1.0
a le PURL suivant :pkg:docker/example/[email protected]
. - N'oubliez pas de spécifier un
author
(c'est un champ obligatoire dans OpenVEX) - La spécification OpenVEX décrit comment
et quand utiliser les champs
justification
,impact_statement
, etc., dans les documents VEX. Spécifier ces champs de manière incorrecte entraîne un document invalide. Assurez-vous que vos documents VEX sont conformes à la spécification OpenVEX.
Attacher des documents VEX aux images
Lorsque vous avez créé un document VEX, vous pouvez l'attacher à votre image de plusieurs manières :
- L'attacher comme attestation
- L'intégrer dans le filesystem de l'image
Vous ne pouvez pas supprimer un document VEX d'une image une fois qu'il a été ajouté. Pour documents attachés comme attestations, vous pouvez créer un nouveau document VEX et l'attacher à l'image à nouveau. Faire cela remplacera le document VEX précédent (mais il ne supprimera pas l'attestation). Pour les images où le document VEX a été intégré dans le filesystem de l'image, vous devez reconstruire l'image pour changer le document VEX.
Attestation
Pour attacher des documents VEX comme attestations, vous pouvez utiliser la commande CLI docker scout attestation add
. Utiliser des attestations est la meilleure option pour
attacher des exceptions à des images lors de l'utilisation de VEX.
Vous pouvez attacher des attestations à des images qui ont déjà été poussées vers un registre. Vous n'avez pas besoin de reconstruire ou de pousser l'image à nouveau. De plus, avoir les exceptions attachées à l'image comme attestations signifie que les consommateurs peuvent inspecter les exceptions pour une image, directement à partir du registre.
Pour attacher une attestation à une image :
-
Construisez l'image et poussez-la vers un registre.
$ docker build --provenance=true --sbom=true --tag <IMAGE> --push .
-
Attachez l'exception à l'image comme attestation.
$ docker scout attestation add \ --file <cve-id>.vex.json \ --predicate-type https://openvex.dev/ns/v0.2.0 \ <IMAGE>
Les options pour cette commande sont :
--file
: le chemin et le nom de fichier du document VEX--predicate-type
: le typepredicateType
in-toto pour OpenVEX
Image filesystem
Intégrer des documents VEX directement dans le filesystem de l'image est une bonne option si
vous connaissez les exceptions à l'avance, avant de construire l'image. Et c'est
relativement facile ; il suffit de COPY
le document VEX dans l'image dans votre Dockerfile.
L'inconvénient avec cette approche est que vous ne pouvez pas changer ou mettre à jour l' exception plus tard. Les couches de l'image sont immuables, donc ce que vous mettez dans le filesystem de l'image est là pour toujours. Attacher le document comme attestation fournit une meilleure flexibilité.
NoteLes documents VEX intégrés dans le filesystem de l'image ne sont pas considérés pour les images qui ont des attestations. Si votre image a tout attestations, Docker Scout ne cherchera des exceptions que dans les attestations, et pas dans le filesystem de l'image.
Si vous souhaitez utiliser le document VEX intégré dans le filesystem de l'image, vous devez supprimer l'attestation de l'image. Notez que des attestations de provenance peuvent être ajoutées automatiquement pour les images. Pour vous assurer que aucune attestations ne sont ajoutées à l'image, vous pouvez explicitement désactiver les SBOM et attestations de provenance en utilisant les drapeaux
--provenance=false
et--sbom=false
lors de la construction de l'image.
Pour intégrer un document VEX dans le filesystem de l'image, COPY
le fichier dans l'image
comme partie du build de l'image. L'exemple suivant montre comment copier tous les documents VEX
sous .vex/
dans le contexte de build, vers /var/lib/db
dans l'image.
# syntax=docker/dockerfile:1
FROM alpine
COPY .vex/* /var/lib/db/
Le nom de fichier du document VEX doit correspondre au motif glob *.vex.json
.
Ce n'a pas d'importance où sur le filesystem de l'image vous stockez le fichier.
Notez que les fichiers copiés doivent être partie du filesystem de l'image finale, Pour les constructions multi-étapes, les documents doivent persister dans la dernière étape.