Ir al contenido

Análisis de Contenedores

Container Scanning es el proceso de analizar imágenes Docker para detectar vulnerabilidades de seguridad. Es un paso crítico en nuestra estrategia DevSecOps, ya que la imagen de contenedor es el artefacto final que se despliega en producción.

En HERA, este análisis se realiza principalmente con Docker Scout, que integra SCA, y se complementa con linters de Dockerfile como Hadolint.

Una imagen no es solo tu código. Es un paquete completo con múltiples capas, y cada una puede tener vulnerabilidades.

Capas de una Imagen Docker
CAPA 4
Código de la Aplicación
Ej: /app/dist/index.js
SAST
CAPA 3
Dependencias de la Aplicación
Ej: /app/node_modules/
SCA
CAPA 2
Runtime y Paquetes del Sistema
Ej: Node.js, npm, curl, openssl
SCA
CAPA 1
Sistema Operativo Base
Ej: Alpine Linux, Debian Slim
SCA
Container Scanning se enfoca en las capas 1, 2 y 3, que son invisibles para herramientas de SAST.
SAST Análisis estático de código fuente
SCA Análisis de composición de software
Mensaje clave Cada capa de la imagen tiene propósito. Multi-stage build minimiza la superficie de ataque.

La seguridad de un contenedor empieza con un Dockerfile bien escrito.

# ✅ SEGURO: Multi-stage y usuario no-root
# 1. Builder Stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 2. Final Stage (Runtime)
FROM node:20-alpine AS final
WORKDIR /app
# Crear usuario no-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Copiar solo los artefactos necesarios desde el builder
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --chown=appuser:appgroup package.json .
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]

Para asegurar que los Dockerfiles sigan las mejores prácticas, el Golden Pipeline incluye Hadolint como job dockerfile-lint en la etapa validate. El equipo de producto no lo escribe a mano — se hereda del template.

AtributoValor
Stagevalidate
Imagen baseHadolint oficial
Alcance del escaneoDockerfile en la raíz del repositorio
TriggerSolo en MRs ($CI_PIPELINE_SOURCE == 'merge_request_event')
allow_failuretrue — no bloquea el pipeline pero deja evidencia de las violaciones
  • DL3006: FROM node en lugar de FROM node:20-alpine (usar :latest está prohibido).
  • DL3002: No se ha cambiado del usuario root (violación de principio non-root).

Al igual que con SCA, el pipeline fallará si se encuentran vulnerabilidades Críticas o Altas. La estrategia de remediación es generalmente una de las siguientes:

  1. Actualizar la imagen base: Es la solución más común. Si tu Dockerfile usa FROM python:3.11.5, y esa versión tiene una vulnerabilidad, cambiar a FROM python:3.11.6 (que ya contiene el parche) usualmente resuelve el problema.

  2. Reconstruir la imagen: A veces, las bases de datos de vulnerabilidades se actualizan. Una simple reconstrucción de la imagen puede resolver vulnerabilidades porque se descargarán las últimas versiones de los paquetes base.

  3. Actualizar un paquete explícitamente: Si una vulnerabilidad está en un paquete que instalas manualmente (ej. con apt-get install curl), puedes forzar su actualización en el Dockerfile.

    # Actualizar paquetes para aplicar parches de seguridad
    RUN apt-get update && apt-get upgrade -y