Saltar al contenido

OpsCanopy 5 min de lectura

Una CVE, cuatro archivos de exclusión: unificando Trivy, Grype, Snyk y osv-scanner

Una única supresión de CVE triada tiene que recodificarse en .trivyignore, .grype.yaml, .snyk y osv-scanner.toml, cada una con una forma distinta. Aquí está la misma supresión en los cuatro formatos, qué se traslada limpiamente y qué se pierde.

  • security
  • vulnerability-management
  • devops

Compartir
En esta página

Una CVE, cuatro archivos de exclusión: unificando los formatos de supresión de Trivy, Grype, Snyk y osv-scanner

Triaste la CVE. Un escáner marcó CVE-2023-45853 en zlib, leíste el aviso, confirmaste que la ruta de código vulnerable no es alcanzable desde tu imagen y tomaste la decisión: suprimirla, con un motivo y una fecha de revisión. Una decisión.

Ahora codifica esa única decisión cuatro veces.

Si tu pipeline ejecuta más de un escáner —y muchos lo hacen, porque Trivy, Grype, Snyk y osv-scanner detectan cada uno cosas que los demás pasan por alto— cada supresión de riesgo aceptado tiene que escribirse en el archivo de exclusión de cada herramienta. La misma CVE, la misma justificación, cuatro archivos distintos con cuatro esquemas distintos, cuatro capacidades distintas. Si te equivocas en uno, ese escáner sigue haciendo fallar el build (o peor, deja de fallar silenciosamente en algo que nunca quisiste ignorar).

La misma supresión, de cuatro maneras

Section 1 of 4 · ~1 min

Aquí está la versión más sencilla de esa decisión —«ignorar CVE-2023-45853»— en cada formato.

.trivyignore es una lista plana delimitada por saltos de línea. Un ID por línea, # para comentarios:

# zlib MiniZip — not reachable from our build, re-review 2026-09-01
CVE-2023-45853

.grype.yaml usa un array ignore estructurado de reglas de coincidencia. Puedes delimitar por ID de vulnerabilidad y, opcionalmente, por paquete:

ignore:
  - vulnerability: CVE-2023-45853
    # zlib MiniZip — not reachable, re-review 2026-09-01
    package:
      name: zlib
      version: 1.2.13

.snyk es el archivo de política de Snyk: un mapa YAML indexado por ID de incidencia, donde cada entrada es una lista de objetos delimitados por ruta que llevan reason y expires como campos de primera clase:

version: v1.25.0
ignore:
  CVE-2023-45853:
    - "*":
        reason: zlib MiniZip not reachable from our build
        expires: 2026-09-01T00:00:00.000Z

osv-scanner.toml usa un array de tablas TOML [[IgnoredVulns]], con id, reason y un ignoreUntil en RFC 3339:

[[IgnoredVulns]]
id = "CVE-2023-45853"
ignoreUntil = 2026-09-01T00:00:00Z
reason = "zlib MiniZip not reachable from our build"

Cuatro archivos. El ID de la CVE es lo único que sobrevive textualmente en todos ellos.

Un ID de CVE irradiando hacia sus cuatro formatos de archivo de exclusión para Trivy, Grype, Snyk y osv-scanner

Qué se traslada limpiamente

Section 2 of 4 · ~1 min

Un puñado de conceptos son genuinamente portables, y un conversor puede moverlos sin pérdida:

  • El identificador. Un ID CVE-… es un ID CVE-… en todas partes. La única peculiaridad: osv-scanner está más cómodo con IDs de OSV (GHSA-…, PYSEC-…) pero acepta CVEs y resuelve alias, mientras que los demás priorizan las CVE. La mayoría de las veces el ID es una copia limpia.
  • Una cadena de motivo. Grype, Snyk y osv-scanner tienen todos algún sitio donde poner el «por qué». Trivy históricamente no lo tenía: en un .trivyignore simple, el único hogar para una justificación es un comentario # en la línea de arriba, que ninguna herramienta analiza pero todo revisor lee.
  • La caducidad, en espíritu. El expires de Snyk y el ignoreUntil de osv-scanner son ambos marcas de tiempo reales y aplicadas: una vez que pasa la fecha, la supresión expira y el hallazgo vuelve. Esa es la misma idea, y se convierte directamente entre las dos.

Qué se pierde

Section 3 of 4 · ~2 min

La parte interesante es todo lo que no hace el viaje de ida y vuelta. Un conversor tiene que ser honesto sobre esto en lugar de descartarlo silenciosamente.

La caducidad es asimétrica. Snyk y osv-scanner aplican una fecha. El .trivyignore simple no tiene campo de caducidad en absoluto: una supresión allí es para siempre hasta que alguien borre la línea. (El archivo de exclusión YAML más reciente de Trivy admite un statement y una coincidencia más rica, pero el .trivyignore clásico que la mayoría de los repos todavía usan no.) Convierte una exclusión de Snyk con caducidad a .trivyignore y esa caducidad solo puede sobrevivir como comentario: una nota para un humano, no una regla que el escáner aplique. Eso es una pérdida real de seguridad, y debería señalarse, no ocultarse.

El alcance del paquete varía. Grype te permite fijar package.name y package.version, de modo que la supresión solo se aplica a esa dependencia exacta. .trivyignore (clásico) se indexa puramente por el ID de la vulnerabilidad: ignora esa CVE en todas partes donde aparezca en el escaneo, lo cual es más amplio de lo que quizás pretendías. Reducir una regla de Grype a .trivyignore amplía el radio de impacto; no puedes expresar «solo este paquete» en una lista plana de IDs.

El alcance de ruta es sobre todo una idea de Snyk. Las entradas ignore de Snyk son listas indexadas por ruta: el "*" de arriba significa «en todas partes», pero Snyk también puede delimitar una supresión a una ruta de dependencia concreta para que se aplique en un sitio y no en otro. Ni Trivy, ni Grype, ni osv-scanner modelan el alcance a nivel de ruta de esta forma, así que una exclusión de Snyk delimitada por ruta se aplana a «esta CVE, a nivel de proyecto» en los demás. La intención («solo en esta ruta transitiva») desaparece.

El motivo no tiene dónde aterrizar de forma nativa en el Trivy clásico. Como antes: convertir hacia .trivyignore degrada un motivo de primera clase a un comentario. Al convertir desde él, normalmente no hay ningún motivo legible por máquina que recuperar, solo lo que un humano dejara en una línea #.

El patrón en todos estos casos: convertir hacia un formato más expresivo es seguro, y convertir hacia uno más plano amplía silenciosamente el alcance y descarta metadatos. La única forma responsable de hacer la conversión plana es exponer exactamente qué se perdió para que un humano pueda decidir si la supresión más amplia es aceptable.

Hazlo una vez, emite cuatro

Section 4 of 4 · ~1 min

Mantener cuatro archivos de exclusión escritos a mano sincronizados es exactamente el tipo de tarea administrativa repetitiva y propensa a errores que debería ser mecánica. Describe una supresión una sola vez —ID, motivo, caducidad, alcance de paquete y de ruta— y deja que una herramienta emita la forma correcta para cada escáner, con advertencias explícitas allá donde un formato de destino no pueda contener un campo.

Eso es lo que hace el CVE-Ignore Converter: pega cualquiera de .trivyignore, .grype.yaml, .snyk o osv-scanner.toml, recibe los otros tres de vuelta y observa con precisión qué partes se perdieron en el viaje de ida y vuelta. Se ejecuta enteramente en tu navegador: tu política de supresión nunca abandona la página.

Prueba el CVE-Ignore Converter →