# 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](/scout/explore/exceptions/) para las vulnerabilidades en las imágenes.

> [!NOTE]
>
> Tambié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](/scout/how-tos/create-exceptions-gui/).

## 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`](https://github.com/openvex/vexctl).
- Tener activado el [almacenamiento de imágenes containerd](/desktop/features/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](https://github.com/openvex/spec). 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 `express@4.17.1`.
- 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.

```console
$ vexctl create \
  --author="author@example.com" \
  --product="pkg:docker/example/app@v1" \
  --subcomponents="pkg:npm/express@4.17.1" \
  --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](https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#docker) 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 `--subcomponents` es el identificador del nombre y la versión del paquete npm (`pkg:npm/express@4.17.1`).

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_affected`
- `affected`
- `fixed`
- `under_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)](https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#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 es `vulnerable_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_present`
- `vulnerable_code_not_present`
- `vulnerable_code_not_in_execute_path`
- `vulnerable_code_cannot_be_controlled_by_adversary`
- `inline_mitigations_already_exist`

Para obtener más información sobre estos valores y sus definiciones, consulta las [justificaciones de estado (Status Justifications)](https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#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:

```json
{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://openvex.dev/docs/public/vex-749f79b50f5f2f0f07747c2de9f1239b37c2bda663579f87a35e5f0fdfc13de5",
  "author": "author@example.com",
  "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/express@4.17.1"
            }
          ]
        }
      ],
      "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](https://github.com/openvex/spec) 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`](https://github.com/openvex/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.

```console
$ 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 llamada `example/myapp:1.0` tiene la siguiente PURL: `pkg:docker/example/myapp@1.0`.
- Recuerda especificar un `author` (es un campo obligatorio en OpenVEX).
- La [especificación de OpenVEX](https://github.com/openvex/spec) describe cómo y cuándo utilizar `justification`, `impact_statement` y 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](#atestacion)
- Integrar el documento en el [sistema de archivos de la imagen](#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:

1. Construye la imagen y súbela a un registro.

   ```console
   $ docker build --provenance=true --sbom=true --tag <IMAGE> --push .
   ```

2. Adjunta la excepción a la imagen como una atestación.

   ```console
   $ 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`: el `predicateType` de 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](#atestacion) proporciona una mayor flexibilidad.

> [!NOTE]
>
> Los 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=false` y `--sbom=false` al 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.

```dockerfile
# 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.

