El Problema: Imágenes Docker sin Escaneo de Seguridad

Desplegar aplicaciones es una parte fundamental del ciclo de desarrollo. Construir una imagen Docker y automatizar su despliegue a producción puede ser un proceso ágil y eficiente. Sin embargo, la automatización sin controles de seguridad adecuados introduce un riesgo significativo. El problema surge cuando estas imágenes Docker, creadas y desplegadas automáticamente, contienen vulnerabilidades conocidas. Sin un paso de verificación de seguridad, estas imágenes pueden llegar a producción, exponiendo la aplicación y los datos a posibles ataques.

Un pipeline de CI/CD tradicional a menudo sigue esta secuencia:

Code
  ↓
Build
  ↓
Test
  ↓
Docker Build
  ↓
Push
  ↓
Deploy

Desde una perspectiva de DevSecOps, este flujo carece de un componente crítico: el escaneo de seguridad. La integración de la seguridad en cada etapa del pipeline es esencial para prevenir la propagación de vulnerabilidades.

Integrando Trivy para un Pipeline DevSecOps Robusto

Para abordar esta brecha de seguridad, es necesario incorporar un paso de escaneo de seguridad en el pipeline. Una herramienta eficaz para esta tarea es Trivy, un escáner de vulnerabilidades de código abierto, fácil de usar y muy rápido. Trivy puede analizar imágenes Docker, sistemas de archivos y repositorios Git en busca de vulnerabilidades y errores de configuración.

Un pipeline de CI/CD mejorado con Trivy para DevSecOps se vería así:

Code
  ↓
Build
  ↓
Test
  ↓
Docker Build
  ↓
Security Scan (Trivy)
  ↓
Push
  ↓
Deploy

En este artículo, exploraremos cómo usar Trivy para analizar una imagen Docker y configurar GitHub Actions para detener el pipeline si se encuentran vulnerabilidades que no cumplen con nuestra política de seguridad predefinida. Esto asegura que solo imágenes seguras lleguen a las etapas posteriores del despliegue.

¿Qué es Trivy?

Trivy (pronunciado 'tree-vy') es un escáner de seguridad de código abierto desarrollado por Aqua Security. Su objetivo es hacer que la seguridad sea accesible para todos los desarrolladores. Trivy es conocido por su simplicidad y velocidad, lo que lo hace ideal para integrarse en pipelines de CI/CD sin añadir una latencia significativa. Escanea:

  • Imágenes de Contenedores: Busca vulnerabilidades en paquetes de SO y dependencias de aplicaciones (npm, pip, gem, etc.).
  • Sistemas de Archivos: Identifica secretos expuestos y configuraciones de infraestructura como código (IaC) inseguras.
  • Repositorios Git: Analiza el historial de Git para detectar secretos que se hayan podido introducir accidentalmente.
  • Archivos de Configuración: Verifica la seguridad de archivos de configuración como Dockerfiles, Kubernetes, Terraform, Ansible, etc.

Trivy utiliza bases de datos de vulnerabilidades actualizadas constantemente, incluyendo NVD (National Vulnerability Database), Red Hat, Debian, Alpine Linux, y repositorios de lenguajes de programación. Su capacidad para generar resultados en varios formatos (como JSON, SARIF, y texto plano) facilita su integración con otras herramientas y plataformas.

Configurando Trivy en GitHub Actions

La integración de Trivy en un pipeline de GitHub Actions implica varios pasos. Primero, necesitamos un archivo de flujo de trabajo (workflow) de GitHub Actions que se active en eventos relevantes, como la creación de una rama o un pull request. Este workflow ejecutará los pasos de construcción de la imagen Docker y, posteriormente, el escaneo con Trivy.

El primer paso es añadir el ejecutable de Trivy al entorno de ejecución de la acción. Esto se puede hacer utilizando la acción oficial de Trivy o descargando el binario directamente.

A continuación, configuramos el comando de escaneo. El comando básico para escanear una imagen Docker es:

trivy image [nombre-de-la-imagen]

Para un control más granular y para que el pipeline falle en caso de vulnerabilidades, podemos especificar políticas de seguridad. Trivy permite definir niveles de severidad mínimos para que el escaneo falle. Por ejemplo, para fallar en la ejecución si se encuentran vulnerabilidades de tipo CRITICAL o HIGH, usaríamos la opción --severity:

trivy image --severity CRITICAL,HIGH [nombre-de-la-imagen]

Si Trivy encuentra alguna vulnerabilidad que coincida con los criterios de severidad especificados, saldrá con un código de error distinto de cero. GitHub Actions interpretará esto como un fallo del paso y detendrá la ejecución del pipeline.

Consideremos un ejemplo de un archivo de flujo de trabajo de GitHub Actions:

name: Docker Image CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-scan:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: Login to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}

    - name: Build and push Docker image
      id: docker_build
      uses: docker/build-push-action@v4
      with:
        push: true
        tags: your-dockerhub-username/your-image-name:latest

    - name: Trivy scan vulnerabilities
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: 'your-dockerhub-username/your-image-name:latest'
        format: 'table'
        ignore-unfixed: true
        format-version: '2'
        hide-progress: false
        # Falla el pipeline si se encuentran vulnerabilidades CRITICAL o HIGH
        severity: 'CRITICAL,HIGH'

En este ejemplo, la acción aquasecurity/trivy-action@master se encarga de ejecutar Trivy contra la imagen especificada. La opción severity: 'CRITICAL,HIGH' es crucial, ya que instruye a Trivy para que falle si detecta vulnerabilidades con estos niveles de criticidad. La opción ignore-unfixed: true es útil para no fallar en vulnerabilidades para las cuales no hay un parche disponible aún, permitiendo al equipo priorizar las vulnerabilidades que sí se pueden solucionar.

Definiendo Políticas de Seguridad con Trivy

La verdadera potencia de integrar Trivy en el CI/CD radica en la capacidad de definir y aplicar políticas de seguridad de manera programática. En lugar de depender de revisiones manuales, el pipeline se convierte en el guardián de la seguridad.

Las políticas de seguridad se pueden definir basándose en:

  • Severidad de la Vulnerabilidad: Como se mostró, se puede configurar Trivy para fallar si se detectan vulnerabilidades de nivel CRITICAL, HIGH, MEDIUM, o LOW.
  • Vulnerabilidades sin Parche (Unfixed): Se puede elegir si el pipeline debe fallar ante vulnerabilidades para las cuales no existe una versión actualizada del paquete o de la imagen.
  • Tipos de Vulnerabilidades: Trivy puede detectar no solo vulnerabilidades de software, sino también secretos expuestos o configuraciones de IaC inseguras. Se pueden configurar escaneos específicos para estos tipos.

Por ejemplo, si una organización tiene una política estricta de no desplegar nada con vulnerabilidades críticas, la configuración severity: 'CRITICAL,HIGH' en el workflow de GitHub Actions asegura que esta política se cumpla automáticamente. Si un desarrollador introduce accidentalmente código o dependencias con estas vulnerabilidades, el pipeline se detendrá antes de que la imagen sea empujada a un registro o desplegada en producción.

La capacidad de Trivy para generar informes en formato SARIF (Static Analysis Results Interchange Format) es particularmente valiosa. SARIF es un estándar abierto que permite la interoperabilidad entre diferentes herramientas de análisis de seguridad. Los informes SARIF generados por Trivy pueden ser procesados por GitHub Security Hub o integrados con otras plataformas de gestión de seguridad, proporcionando una vista unificada de las vulnerabilidades detectadas en el código y las imágenes.

Más Allá del Escaneo de Imágenes

Si bien el enfoque principal de este artículo es el escaneo de imágenes Docker, Trivy ofrece capacidades mucho más amplias que pueden fortalecer aún más un pipeline de CI/CD. Trivy también puede escanear:

  • Archivos de Configuración de Kubernetes: Detecta configuraciones inseguras en archivos YAML de Kubernetes, como la falta de límites de recursos, la ejecución de contenedores como root, o el uso de imágenes privilegiadas.
  • Infraestructura como Código (IaC): Escanea archivos de Terraform, CloudFormation, Ansible, y Kubernetes para identificar configuraciones de seguridad deficientes en la nube.
  • Secretos: Busca credenciales, claves API y otros secretos que puedan haber sido accidentalmente codificados en el repositorio o en la imagen.

Integrar estos escaneos en etapas tempranas del pipeline (incluso antes de construir la imagen Docker) puede prevenir la introducción de configuraciones de riesgo en la infraestructura y en el código base. Por ejemplo, un escaneo de Terraform podría detectar que se está intentando desplegar una base de datos sin encriptación, deteniendo el proceso antes de que se provisione infraestructura vulnerable.

Beneficios de la Integración

La integración de Trivy en el pipeline de CI/CD ofrece múltiples beneficios:

  • Detección Temprana: Las vulnerabilidades se identifican en las primeras etapas del ciclo de vida del desarrollo, reduciendo drásticamente el costo y el esfuerzo de remediación.
  • Automatización de la Seguridad: La aplicación de políticas de seguridad se automatiza, eliminando la dependencia de revisiones manuales propensas a errores.
  • Reducción del Riesgo: Se minimiza la probabilidad de desplegar imágenes o configuraciones vulnerables en producción.
  • Cumplimiento Normativo: Ayuda a cumplir con estándares de seguridad y regulaciones que exigen escaneos de vulnerabilidades.
  • Mejora de la Cultura DevSecOps: Fomenta una mentalidad de seguridad compartida entre los equipos de desarrollo y operaciones.

Bloquear imágenes Docker vulnerables antes del deploy no es solo una buena práctica; es una necesidad en el panorama de amenazas actual. Herramientas como Trivy proporcionan la capacidad de automatizar esta protección, permitiendo a los equipos centrarse en la innovación mientras mantienen un alto nivel de seguridad.