Escanear Docker Hardened Images
Las Docker Hardened Images (DHI) están diseñadas para ser seguras por defecto, pero como con cualquier otra imagen de contenedor, es importante escanearlas regularmente como parte de tu proceso de gestión de vulnerabilidades.
Escanear con escáneres compatibles con OpenVEX
Para obtener evaluaciones de vulnerabilidad precisas, utiliza escáneres que admitan atestaciones VEX. Los siguientes escáneres pueden leer y aplicar las declaraciones VEX incluidas con las Docker Hardened Images:
- Docker Scout: Aplica automáticamente las declaraciones VEX sin necesidad de configuración.
- Trivy: Admite VEX a través de VEX Hub o archivos VEX locales.
- Grype: Admite VEX mediante la opción
--vex. - Wiz: Aplica automáticamente las declaraciones VEX sin necesidad de configuración.
- Mend.io: Aplica automáticamente las declaraciones VEX sin necesidad de configuración.
Para obtener orientación sobre cómo elegir el escáner adecuado y comprender las diferencias entre los escáneres con VEX habilitado y los que no lo tienen, consulta Integraciones de escáneres.
Docker Scout
Docker Scout está integrado en Docker Desktop y en la CLI de Docker. Proporciona información sobre vulnerabilidades, resúmenes de CVE y enlaces directos a guías de remediación.
Escanear una DHI usando Docker Scout
Para escanear una Docker Hardened Image usando Docker Scout, ejecuta el siguiente comando:
$ docker login dhi.io
$ docker scout cves dhi.io/<image>:<tag> --platform <platform>
Ejemplo de salida:
SBOM obtenido de la atestación, se encontraron 101 paquetes
Procedencia obtenida de la atestación
Declaraciones VEX obtenidas de la atestación
No se detectó ningún paquete vulnerable
...Para un filtrado más detallado y salida en formato JSON, consulta la referencia de la CLI de Docker Scout.
Compilar imágenes hijas con atestaciones de procedencia
Al compilar una imagen personalizada que utiliza una Docker Hardened Image como base, debes compilar con --provenance=mode=max y --sbom=true para que Docker Scout pueda rastrear el linaje de la imagen base y aplicar correctamente las declaraciones VEX.
Sin estas opciones, Docker Scout no puede identificar la imagen base de DHI en la cadena de procedencia. Como resultado, reportará CVE que ya están suprimidos por las declaraciones VEX en la imagen base, produciendo falsos positivos de CVE en los resultados del escaneo.
NotePor qué se requiere la atestación de procedencia
Docker Scout utiliza atestaciones de procedencia en modo max para identificar la imagen base de DHI y rastrear su linaje. Una atestación de procedencia firmada criptográficamente garantiza que el linaje de la imagen base esté verificado y sea resistente a la manipulación, lo que le da a Docker Scout el punto de confianza que necesita para aplicar correctamente las declaraciones VEX de la imagen base.
Para compilar con el máximo nivel de procedencia y atestaciones SBOM:
$ docker build \
--provenance=mode=max \
--sbom=true \
--push \
-t docker.io/<namespace>/<image>:<tag> .
Después de compilar con estas opciones, Docker Scout lee la cadena de procedencia completa, hace coincidir la imagen base de DHI y aplica sus declaraciones VEX. Los escaneos de tu imagen hija reflejarán entonces los CVE suprimidos correctos, lo que te dará una evaluación de vulnerabilidad precisa.
Atestaciones VEX en imágenes hijas
Si introduces nuevas capas en tu imagen hija y quieres suprimir CVE en esas capas, puedes adjuntar tu propia atestación VEX a la imagen hija de forma independiente; no necesitas duplicar ni agregar las declaraciones VEX de la imagen base de DHI.
Cuando docker scout cves se ejecuta en tu imagen hija, Scout lee las atestaciones VEX de la cadena de procedencia completa y las aplica de forma acumulativa:
- VEX de la imagen base: adjunta a la DHI, se aplica a los CVE en las capas de la imagen base.
- VEX de la imagen hija: adjunta a tu imagen, se aplica a los CVE en las capas que introdujiste.
Por ejemplo, si añades una capa requests a una imagen base DHI de Python y adjuntas una declaración VEX que suprime CVE-2024-47081, Scout aplica ambas atestaciones VEX de forma independiente y atribuye cada una a su respectivo autor:
✓ VEX statements obtained from attestation
CVE-2024-47081 VEX: not affected [vulnerable code not present] : <your-namespace>Scout suprime los CVE de la VEX base de la DHI y los CVE de tu VEX de la imagen hija en el mismo escaneo; no se requiere ningún documento VEX agregado.
Para crear y adjuntar una atestación VEX a tu imagen hija:
cat > child-vex.json << 'EOF'
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://<your-namespace>/vex/<image-name>/1",
"author": "<your-namespace>",
"timestamp": "<timestamp>",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "<CVE-ID>"
},
"products": [
{
"@id": "pkg:pypi/<package>@<version>"
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_present"
}
]
}
EOF
docker scout attestation add \
--file child-vex.json \
--predicate-type https://openvex.dev/ns/v0.2.0 \
docker.io/<your-namespace>/<image>:<tag>NoteEsto solo es posible porque compilaste con
--provenance=mode=max. Sin la cadena de procedencia completa, Scout no puede retroceder hasta la imagen base para recuperar sus atestaciones VEX.
Automatizar el escaneo de DHI en CI/CD con Docker Scout
Integrar Docker Scout en tu pipeline de CI/CD te deja verificar automáticamente que las imágenes compiladas a partir de Docker Hardened Images permanezcan libres de vulnerabilidades conocidas durante el proceso de compilación. Este enfoque proactivo garantiza la integridad continua de la seguridad de tus imágenes a lo largo del ciclo de vida del desarrollo.
Ejemplo de flujo de trabajo de GitHub Actions
El siguiente es un ejemplo de flujo de trabajo de GitHub Actions que compila una imagen, la escanea y la sube al registro solo si el escaneo tiene éxito:
name: DHI Vulnerability Scan
on:
push:
branches:
- main
pull_request:
env:
REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository }}
SHA: ${{ github.event.pull_request.head.sha || github.event.after }}
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker with containerd image store
uses: docker/setup-docker-action@v5
with:
daemon-config: |
{
"features": {
"containerd-snapshotter": true
}
}
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build
uses: docker/build-push-action@v7
with:
context: .
sbom: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.SHA }}
- name: Run Docker Scout CVE scan
uses: docker/scout-action@v1
with:
command: cves
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.SHA }}
only-severities: critical,high
exit-code: true
- name: Push image
if: success()
run: |
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.SHA }}El parámetro exit-code: true garantiza que el flujo de trabajo falle si se detecta alguna vulnerabilidad de gravedad crítica o alta, evitando el despliegue de imágenes inseguras.
NoteLas opciones
--provenance=mode=maxy--sbom=trueson necesarias para que Docker Scout pueda rastrear el linaje de la imagen base de DHI y aplicar correctamente sus declaraciones VEX. Habilitar el almacenamiento de imágenes containerd a través dedocker/setup-docker-actionpermite a BuildKit almacenar las atestaciones localmente sin subirlas primero a un registro. Sin el almacenamiento de imágenes containerd, Docker Engine rechaza la compilación con:Attestation is not supported for the docker driver. Switch to a different driver, or turn on the containerd image store, and try again.El pasoPush imagese ejecuta solo si el escaneo tiene éxito, utilizandoif: success()para garantizar que las imágenes solo se suban al registro cuando estén libres de vulnerabilidades críticas o altas.
Para obtener más detalles sobre el uso de Docker Scout en CI, consulta Integrar Docker Scout con otros sistemas.
Grype
Grype es un escáner de código abierto que comprueba las imágenes de contenedor contra bases de datos de vulnerabilidades como la NVD y los avisos de las distribuciones.
Escanear una DHI usando Grype
Para escanear una Docker Hardened Image usando Grype con filtrado VEX, primero exporta la atestación VEX y luego realiza el escaneo con la opción --vex:
$ docker login dhi.io
$ docker pull dhi.io/<image>:<tag>
$ docker scout vex get dhi.io/<image>:<tag> --output vex.json
$ grype dhi.io/<image>:<tag> --vex vex.json
La opción --vex aplica las declaraciones VEX durante el escaneo, filtrando los CVE conocidos que no son explotables para obtener resultados precisos.
Para obtener más información sobre la exportación de atestaciones VEX, consulta Exportar atestaciones VEX.
Trivy
Trivy es un escáner de vulnerabilidades de código abierto para contenedores y otros artefactos. Detecta vulnerabilidades en paquetes del sistema operativo y dependencias de aplicaciones.
Escanear una DHI usando Trivy
Después de instalar Trivy, puedes escanear una Docker Hardened Image descargando la imagen y ejecutando el comando de escaneo:
$ docker login dhi.io
$ docker pull dhi.io/<image>:<tag>
$ trivy image --scanners vuln dhi.io/<image>:<tag>
Para filtrar las vulnerabilidades utilizando declaraciones VEX, Trivy admite múltiples enfoques. Docker recomienda usar VEX Hub, que ofrece un flujo de trabajo directo para descargar y aplicar automáticamente declaraciones VEX desde repositorios configurados.
Uso de VEX Hub (recomendado)
Configura Trivy para descargar el repositorio de avisos de Docker Hardened Images desde VEX Hub. Ejecuta los siguientes comandos para configurar el repositorio VEX:
$ trivy vex repo init
$ cat << REPO > ~/.trivy/vex/repository.yaml
repositories:
- name: default
url: https://github.com/aquasecurity/vexhub
enabled: true
username: ""
password: ""
token: ""
- name: dhi-vex
url: https://github.com/docker-hardened-images/advisories
enabled: true
REPO
$ trivy vex repo list
$ trivy vex repo download
Después de configurar VEX Hub, puedes escanear una Docker Hardened Image con filtrado VEX:
$ docker login dhi.io
$ docker pull dhi.io/<image>:<tag>
$ trivy image --scanners vuln --vex repo dhi.io/<image>:<tag>
Por ejemplo, escanear la imagen dhi.io/python:3.13:
$ trivy image --scanners vuln --vex repo dhi.io/python:3.13
Ejemplo de salida:
Report Summary
┌─────────────────────────────────────────────────────────────────────────────┬────────────┬─────────────────┐
│ Target │ Type │ Vulnerabilities │
├─────────────────────────────────────────────────────────────────────────────┼────────────┼─────────────────┤
│ dhi.io/python:3.13 (debian 13.2) │ debian │ 0 │
├─────────────────────────────────────────────────────────────────────────────┼────────────┼─────────────────┤
│ opt/python-3.13.11/lib/python3.13/site-packages/pip-25.3.dist-info/METADATA │ python-pkg │ 0 │
└─────────────────────────────────────────────────────────────────────────────┴────────────┴─────────────────┘
Legend:
- '-': Not scanned
- '0': Clean (no security findings detected)La opción --vex repo aplica las declaraciones VEX del repositorio configurado durante el escaneo, lo que filtra los CVE no explotables conocidos.
Uso de archivos VEX locales
Además de VEX Hub, Trivy también admite el uso de archivos VEX locales para el filtrado de vulnerabilidades. Puedes descargar la atestación VEX que proporcionan las Docker Hardened Images y utilizarla directamente con Trivy.
Primero, descarga la atestación VEX para tu imagen:
$ docker scout vex get dhi.io/<image>:<tag> --output vex.json
Luego escanea la imagen con el archivo VEX local:
$ trivy image --scanners vuln --vex vex.json dhi.io/<image>:<tag>
Wiz
Wiz es una plataforma de seguridad en la nube que incluye capacidades de escaneo de imágenes de contenedor compatibles con las atestaciones DHI VEX. Wiz CLI consume automáticamente las declaraciones VEX de las Docker Hardened Images para proporcionar evaluaciones de vulnerabilidad precisas.
Escanear una DHI usando Wiz CLI
Después de adquirir una suscripción a Wiz e instalar Wiz CLI, puedes escanear una Docker Hardened Image descargando la imagen y ejecutando el comando de escaneo:
$ docker login dhi.io
$ docker pull dhi.io/<image>:<tag>
$ wizcli scan container-image dhi.io/<image>:<tag>
Mend.io
Mend.io es una plataforma de seguridad de aplicaciones que incluye el escaneo de imágenes de contenedor compatible con las atestaciones DHI VEX. Mend Container recupera y aplica automáticamente las declaraciones VEX de las Docker Hardened Images y las combina con el análisis de alcanzabilidad de Mend para una evaluación de vulnerabilidad completa.
Escanear una DHI usando Mend.io
Después de adquirir una suscripción a Mend.io y configurar Mend Container, Mend detecta automáticamente las Docker Hardened Images y aplica sus datos VEX sin requerir ninguna configuración adicional. Cuando escaneas una Docker Hardened Image a través de la plataforma Mend AppSec, las declaraciones VEX se recuperan automáticamente y se adjuntan como factores de riesgo a cada hallazgo.
Puedes ver y filtrar los hallazgos específicos de DHI en la plataforma Mend AppSec bajo Security > Containers > Packages, donde una insignia de Docker identifica los paquetes de imágenes securizadas. Utiliza la columna Risk Factors para filtrar por estados VEX como Not Affected (No afectado), Fixed (Corregido) o Under Investigation (En investigación).
Para obtener más información, consulta la documentación de Mend.io para Docker Hardened Images.
Exportar atestaciones VEX
Para los escáneres que necesitan archivos VEX locales (como Grype o Trivy con archivos locales), puedes exportar las atestaciones VEX de las Docker Hardened Images.
NotePor defecto, las atestaciones VEX se recuperan de
registry.scout.docker.com. Asegúrate de que puedes acceder a este registro si tu red tiene restricciones de salida. También puedes replicar las atestaciones en un registro alternativo. Para obtener más detalles, consulta Replicar en un registro de terceros.
Exporta las atestaciones VEX a un archivo JSON:
$ docker scout vex get dhi.io/<image>:<tag> --output vex.json
NoteEl comando
docker scout vex getrequiere la versión 1.18.3 o posterior de la CLI de Docker Scout.Si la imagen existe localmente en tu dispositivo, debes anteponer al nombre de la imagen el prefijo
registry://. Por ejemplo, usaregistry://docs/dhi-python:3.13en lugar dedocs/dhi-python:3.13.