Crear una excepción utilizando VEX
Vulnerability Exploitability eXchange (VEX) es un formato estándar para documentar vulnerabilidades en el contexto de un producto o paquete de software. Docker Scout es compatible con los documentos VEX para crear excepciones para las vulnerabilidades en las imágenes.
NoteTambién puedes crear excepciones utilizando el Panel de Docker Scout o Docker Desktop. La interfaz gráfica proporciona una experiencia intuitiva para crear excepciones y resulta sencillo gestionar excepciones para múltiples imágenes. También te permite crear excepciones para múltiples imágenes, o para toda tu organización, todo a la vez. Para obtener más información, consulta Crear una excepción utilizando la interfaz gráfica.
Requisitos previos
Para crear excepciones utilizando documentos OpenVEX, necesitas:
- La versión más reciente de Docker Desktop o del plugin de la CLI de Docker Scout.
- La herramienta de línea de comandos
vexctl. - Tener activado el almacenamiento de imágenes containerd.
- Permisos de escritura en el repositorio del registro donde está almacenada la imagen.
Introducción a VEX
El estándar VEX está definido por un grupo de trabajo de la Agencia de Seguridad de Infraestructura y Ciberseguridad de los Estados Unidos (CISA). En el núcleo de VEX se encuentran las evaluaciones de explotabilidad. Estas evaluaciones describen el estado de un CVE determinado para un producto. Los posibles estados de vulnerabilidad en VEX son:
- Not affected (No afectado): No se requiere ninguna medida correctiva con respecto a esta vulnerabilidad.
- Affected (Afectado): Se recomiendan acciones para corregir o abordar esta vulnerabilidad.
- Fixed (Corregido): Estas versiones del producto contienen una corrección para la vulnerabilidad.
- Under investigation (Bajo investigación): Aún no se sabe si estas versiones del producto están afectadas por la vulnerabilidad. Se proporcionará una actualización en una versión posterior.
Existen múltiples implementaciones y formatos de VEX. Docker Scout es compatible con la implementación OpenVex. Independientemente de la implementación específica, la idea central es la misma: proporcionar un marco para describir el impacto de las vulnerabilidades. Los componentes clave de VEX, sin importar la implementación, incluyen:
- Documento VEX
- Un tipo de aviso de seguridad para almacenar declaraciones VEX. El formato del documento depende de la implementación específica.
- Declaración VEX
- Describe el estado de una vulnerabilidad en un producto, si es explotable y si existen formas de corregir el problema.
- Justificación e impacto
- Dependiendo del estado de la vulnerabilidad, las declaraciones incluyen una justificación o una declaración de impacto que describe por qué un producto está o no afectado.
- Declaraciones de acción
- Describen cómo corregir o mitigar la vulnerabilidad.
Ejemplo de vexctl
El siguiente comando de ejemplo crea un documento VEX que establece que:
- El producto de software descrito por este documento VEX es la imagen de Docker
example/app:v1. - La imagen contiene el paquete npm
[email protected]. - El paquete npm está afectado por una vulnerabilidad conocida:
CVE-2022-24999. - La imagen no está afectada por el CVE porque el código vulnerable nunca se ejecuta en los contenedores que ejecutan esta imagen.
$ 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"
A continuación se describen las opciones de este ejemplo:
--author- El correo electrónico del autor del documento VEX.
--product- URL del paquete (PURL) de la imagen de Docker. Una PURL es un identificador para la imagen en un formato estandarizado, definido en la especificación de PURL.
Las cadenas PURL de imágenes de Docker comienzan con el prefijo de tipo pkg:docker, seguido por el repositorio y la versión de la imagen (la etiqueta de la imagen o el resumen SHA256). A diferencia de las etiquetas de imagen, donde la versión se especifica como example/app:v1, en PURL el repositorio y la versión de la imagen están separados por una @.
--subcomponents- PURL del paquete vulnerable en la imagen. En este ejemplo, la vulnerabilidad existe en un paquete npm, por lo que la PURL de
--subcomponentses el identificador del nombre y la versión del paquete npm (pkg:npm/[email protected]).
Si la misma vulnerabilidad existe en múltiples paquetes, vexctl te permite especificar la bandera --subcomponents varias veces para un único comando create.
También puedes omitir --subcomponents, en cuyo caso la declaración VEX se aplica a toda la imagen.
--vuln- ID del CVE que aborda la declaración VEX.
--status- Esta es la etiqueta de estado de la vulnerabilidad. Describe la relación entre el software (
--product) y el CVE (--vuln). Los valores posibles para la etiqueta de estado en OpenVEX son:
not_affectedaffectedfixedunder_investigation
En este ejemplo, la declaración VEX afirma que la imagen de Docker no está afectada (not_affected) por la vulnerabilidad. El estado not_affected es el único que da como resultado la supresión de la CVE, donde la CVE se filtra de los resultados del análisis. Los otros estados son útiles para fines de documentación, pero no sirven para crear excepciones. Para obtener más información sobre todas las etiquetas de estado posibles, consulta las etiquetas de estado (Status Labels) en la especificación de OpenVEX.
--justification- Justifica la etiqueta de estado
not_affected, informando por qué el producto no está afectado por la vulnerabilidad. En este caso, la justificación dada esvulnerable_code_not_in_execute_path, lo que indica que la vulnerabilidad no se puede ejecutar tal como la utiliza el producto.
En OpenVEX, las justificaciones de estado pueden tener uno de los siguientes cinco valores posibles:
component_not_presentvulnerable_code_not_presentvulnerable_code_not_in_execute_pathvulnerable_code_cannot_be_controlled_by_adversaryinline_mitigations_already_exist
Para obtener más información sobre estos valores y sus definiciones, consulta las justificaciones de estado (Status Justifications) en la especificación de OpenVEX.
--file- Nombre del archivo de salida del documento VEX.
Ejemplo de documento JSON
Este es el JSON de OpenVEX generado por este comando:
{
"@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"
}
]
}Comprender cómo se estructuran los documentos VEX puede resultar un poco complejo. La especificación de OpenVEX describe el formato y todas las propiedades posibles de los documentos y declaraciones. Para obtener todos los detalles, consulta la especificación para aprender más sobre los campos disponibles y cómo crear un documento OpenVEX bien formado.
Para obtener más información sobre las banderas disponibles y la sintaxis de la herramienta de CLI vexctl y cómo instalarla, consulta el repositorio de GitHub de vexctl.
Verificar documentos VEX
Para probar si los documentos VEX que creas están bien formados y producen los resultados esperados, utiliza el comando docker scout cves con la bandera --vex-location para aplicar un documento VEX a un análisis de imagen local utilizando la CLI.
El siguiente comando invoca un análisis de imagen local que incorpora todos los documentos VEX en la ubicación especificada, utilizando la bandera --vex-location. En este ejemplo, se le indica a la CLI que busque documentos VEX en el directorio de trabajo actual.
$ docker scout cves <IMAGE> --vex-location .
La salida del comando docker scout cves muestra los resultados teniendo en cuenta las declaraciones VEX encontradas bajo la ubicación de --vex-location. Por ejemplo, los CVEs asignados con el estado not_affected se filtran de los resultados. Si la salida no parece tener en cuenta las declaraciones VEX, esto es una indicación de que los documentos VEX podrían ser inválidos de alguna manera.
Aspectos a tener en cuenta:
- La PURL de una imagen de Docker debe comenzar con
pkg:docker/seguido del nombre de la imagen. - En una PURL de imagen de Docker, el nombre de la imagen y la versión se separan con
@. Una imagen llamadaexample/myapp:1.0tiene la siguiente PURL:pkg:docker/example/[email protected]. - Recuerda especificar un
author(es un campo obligatorio en OpenVEX). - La especificación de OpenVEX describe cómo y cuándo utilizar
justification,impact_statementy otros campos en los documentos VEX. Especificar estos campos de forma incorrecta dará como resultado un documento no válido. Asegúrate de que tus documentos VEX cumplan con la especificación de OpenVEX.
Adjuntar documentos VEX a las imágenes
Una vez que hayas creado un documento VEX, puedes adjuntarlo a tu imagen de las siguientes maneras:
- Adjuntar el documento como una atestación
- Integrar el documento en el sistema de archivos de la imagen
No puedes eliminar un documento VEX de una imagen una vez añadido. Para los documentos adjuntados como atestaciones, puedes crear un nuevo documento VEX y volver a adjuntarlo a la imagen. Al hacerlo, se sobrescribirá el documento VEX anterior (pero no se eliminará la atestación). Para las imágenes donde el documento VEX se ha integrado en el sistema de archivos de la imagen, debes volver a construir la imagen para cambiar el documento VEX.
Atestación
Para adjuntar documentos VEX como una atestación, puedes utilizar el comando de la CLI docker scout attestation add. El uso de atestaciones es la opción recomendada para adjuntar excepciones a las imágenes al utilizar VEX.
Puedes adjuntar atestaciones a imágenes que ya han sido subidas a un registro. No necesitas construir ni subir la imagen de nuevo. Además, tener las excepciones adjuntas a la imagen como atestaciones permite a los consumidores inspeccionar las excepciones de una imagen directamente desde el registro.
Para adjuntar una atestación a una imagen:
Construye la imagen y súbela a un registro.
$ docker build --provenance=true --sbom=true --tag <IMAGE> --push .Adjunta la excepción a la imagen como una atestación.
$ docker scout attestation add \ --file <cve-id>.vex.json \ --predicate-type https://openvex.dev/ns/v0.2.0 \ <IMAGE>Las opciones para este comando son:
--file: la ubicación y el nombre del archivo del documento VEX--predicate-type: elpredicateTypede in-toto para OpenVEX
Sistema de archivos de la imagen
Integrar los documentos VEX directamente en el sistema de archivos de la imagen es una buena opción si conoces las excepciones de antemano, antes de construir la imagen. Y es relativamente sencillo; basta con copiar (COPY) el documento VEX en la imagen en tu Dockerfile.
La desventaja de este enfoque es que no puedes cambiar o actualizar la excepción más adelante. Las capas de la imagen son inmutables, por lo que cualquier cosa que coloques en el sistema de archivos de la imagen permanecerá allí para siempre. Adjuntar el documento como una atestación proporciona una mayor flexibilidad.
NoteLos documentos VEX integrados en el sistema de archivos de la imagen no se tienen en cuenta en las imágenes que tienen atestaciones. Si tu imagen tiene cualquier atestación, Docker Scout únicamente buscará excepciones en las atestaciones y no en el sistema de archivos de la imagen.
Si deseas utilizar el documento VEX integrado en el sistema de archivos de la imagen, debes eliminar la atestación de la imagen. Ten en cuenta que las atestaciones de procedencia se pueden añadir automáticamente a las imágenes. Para asegurarte de que no se añadan atestaciones a la imagen, puedes desactivar explícitamente tanto las atestaciones de SBOM como las de procedencia utilizando las banderas
--provenance=falsey--sbom=falseal construir la imagen.
Para integrar un documento VEX en el sistema de archivos de la imagen, utiliza COPY para copiar el archivo en la imagen como parte de la construcción de la misma. El siguiente ejemplo muestra cómo copiar todos los documentos VEX bajo .vex/ en el contexto de construcción al directorio /var/lib/db en la imagen.
# syntax=docker/dockerfile:1
FROM alpine
COPY .vex/* /var/lib/db/El nombre del archivo del documento VEX debe coincidir con el patrón de coincidencia *.vex.json. No importa en qué lugar del sistema de archivos de la imagen almacenes el archivo.
Ten en cuenta que los archivos copiados deben formar parte del sistema de archivos de la imagen final. Para construcciones multietapa, los documentos deben persistir en la etapa final.