⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

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.

Note

Vous 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 comme example/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 commande create.

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 statut not_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 est vulnerable_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ée example/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 :

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 :

  1. Construisez l'image et poussez-la vers un registre.

    $ docker build --provenance=true --sbom=true --tag <IMAGE> --push .
    
  2. 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 type predicateType 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é.

Note

Les 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.