Aikido

La seguridad de contenedores es difícil — Aikido Container AutoFix para facilitarla

Mackenzie JacksonMackenzie Jackson
|
#
#
#

La seguridad de contenedores comienza con tu imagen base.
Pero aquí está el truco:

  • Simplemente actualizar a la versión "latest" de una imagen base puede romper tu aplicación.
  • Te ves obligado a elegir entre lanzar con vulnerabilidades conocidas o pasar días solucionando problemas de compatibilidad.
  • Y a menudo... ni siquiera estás seguro de si una actualización merece la pena.

En esta publicación, exploraremos por qué actualizar las imágenes base es más difícil de lo que parece, veremos ejemplos reales y mostraremos cómo puedes automatizar actualizaciones seguras e inteligentes sin romper tu aplicación.

El problema: “Simplemente actualiza tu imagen base” — Más fácil de decir que de hacer

Si estás leyendo esto, probablemente hayas buscado en Google algo como “Cómo proteger tus contenedores” y el primer punto en cada artículo genérico generado por IA que hayas leído es este: actualiza tu imagen base. Sencillo, ¿verdad? Pues no tan rápido. 

Tu imagen base es tu punto central de seguridad; si tu imagen base tiene vulnerabilidades, tu aplicación las arrastrará consigo. Veamos este escenario. 

Ejecutas un escaneo en tu imagen de contenedor y se encuentra una CVE de alta severidad. La útil recomendación es actualizar la imagen base, fantástico, habrás terminado antes de comer. 

⚠️ CVE-2023-37920 encontrada en ubuntu:20.04
Severidad: Alta
Corregida en: 22.04
Recomendación: Actualizar imagen base

…pero descubres un problema. 

Al actualizar ciegamente desde ubuntu:20.04 con ubuntu:22.04, tu aplicación se rompe.

Veamos algunos ejemplos de cómo actualizar una imagen base y qué sucede en la realidad. 

Ejemplo 1: Un Dockerfile que se rompe después de una actualización

Dockerfile inicial:

FROM python:3.8-buster‍
RUN apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2
COPY . /appCMD ["python", "app.py"]

El equipo actualiza a:

FROM python:3.11-bookworm‍
RUN apt-get update && apt-get install -y libpq-dev
RUN pip install psycopg2==2.8.6 flask==1.1.2COPY . /appCMD ["python", "app.py"]

Resultado:

  • psycopg2==2.8.6 falla al compilar con versiones más recientes de libpq cabeceras en bookworm.
  • flask==1.1.2 no soporta Python 3.11 características en tiempo de ejecución (las APIs obsoletas fallan).
  • La compilación falla en CI.
  • Tu equipo de desarrollo está furioso y tu almuerzo, arruinado. 

Ejemplo 2: Actualizaciones de imágenes base que introducen errores sutiles en tiempo de ejecución

Original:

FROM node:14-busterCOPY . /app
RUN npm ci
CMD ["node", "server.js"]

Actualización a:

FROM node:20-bullseye
COPY . /app
RUN npm ci
CMD ["node", "server.js"]

Problema en tiempo de ejecución:

  • node:20 utiliza versiones más recientes de OpenSSL — la verificación TLS estricta rompe las configuraciones antiguas de axios.
  • La aplicación lanza UNABLE_TO_VERIFY_LEAF_SIGNATURE errores en tiempo de ejecución HTTP en llamadas a servicios heredados.

Por qué «latest» es una trampa

El ecosistema Docker fomenta el uso de las últimas etiquetas o versiones principales. Pero esto a menudo significa que su aplicación, que funcionaba el lunes, falla repentinamente el martes. Esto es a menudo una trampa que causará dolores de cabeza, interrupciones y un desarrollo más lento a medida que se dedica tiempo a corregir errores. 

Así que la solución obvia es fijarse a una versión menor que haya probado…. No tan rápido, ya que ahora ha entrado en el juego del 'whack-a-mole' de seguridad, donde estará descubriendo constantemente nuevas CVEs que podrían dejarle vulnerable. 

Parálisis de decisión: ¿Debería actualizar o no?

Los equipos de seguridad presionan para las actualizaciones.
Los desarrolladores se resisten debido a la estabilidad.

¿Quién tiene razón? Depende.

PERO, para siquiera entender la decisión, necesita considerar todas las opciones, lo que significa crear una hoja de cálculo masiva con todas las versiones, riesgos de seguridad, riesgos de estabilidad y disponibilidad. 

Veamos cómo podría ser. 

Etiqueta de versión CVEs presentes (Altas/Críticas) Riesgo de compatibilidad (1-5) Cambios disruptivos clave / Riesgo funcional Soporte binario del ecosistema (Binarios Wheels/NPM)
node:14-buster (Actual) - CVE-2022-35256 (desbordamiento de búfer de OpenSSL)
- CVE-2022-25883 (SSRF en node-fetch)
- CVE-2021-32803 (contaminación de prototipos en object-path)
1 (Estable pero envejeciendo) TLS heredado, dependencias inseguras integradas Totalmente compatible pero EOL (mantenimiento detenido en abril de 2023)
node:14-bullseye - Las mismas CVEs que las anteriores + problemas adicionales menores de OpenSSL 1 Cambios menores en glibc
Posibles cambios de compatibilidad en la capa de tiempo de ejecución de Docker
Estable; el ecosistema de wheel y NPM aún lo soporta
node:16-buster - CVE-2023-30581 (escritura fuera de límites de libuv)
- CVE-2022-35256 (desbordamiento de OpenSSL)
- CVE-2022-25883 (SSRF en node-fetch)
2 Advertencias de deprecación del constructor Buffer()
Las bibliotecas HTTP heredadas emiten advertencias estrictas
Amplio soporte
node:16-bullseye - Igual que lo anterior + actualizaciones menores de OpenSSL 2 Comportamiento ligeramente diferente del resolvedor DNS
Necesita cobertura de pruebas para las llamadas de red internas
Compatible
node:18-bullseye - CVE-2022-45195 (vulnerabilidad TLS en una compilación antigua)
- CVE-2023-30581 (escritura OOB de libuv)
3 Modo estricto TLS por defecto
Axios heredado y las librerías de solicitud más antiguas fallan con certificados estrictos.
Ecosistema en madurez intermedia; algunos módulos requieren actualizaciones
node:18-alpine - Igual que el anterior; riesgos de desajuste de glibc en Alpine 4 Alpine musl puede romper ciertos módulos nativos como bcrypt
Problemas de fallback en la compilación desde el código fuente
Necesita reconstrucciones para binarios nativos
node:20-bullseye - 0 CVEs de gravedad alta (versión estable actual) 4 Breaking DNS resolver changes
Default ESM loader changes
axios < 1.3.2 breaks
Con soporte activo; el ecosistema se está poniendo al día
node:20-bookworm (última versión) - 0 CVEs de gravedad alta (a marzo de 2024) 5 Cambios importantes:
TLS estricto
Cambios de DNS
Aplicación de ESM
Los plugins de NPM antiguos fallan
Algunos módulos de nicho aún se están poniendo al día; se requiere la última versión de node-gyp.

Esto te deja con opciones complejas, deficientes e imposibles. 

  1. Mantenerse en la imagen antigua y aceptar vulnerabilidades
  2. Actualiza y rompe tu aplicación, arriesgando el tiempo de inactividad en producción
  3. Intentar pruebas de compatibilidad manuales — días de trabajo

El flujo de trabajo de actualización manual:

Si está haciendo esto manualmente, así es como se ve:

  • Verificar CVEs: trivy image python:3.8-buster
  • Investigar cada CVE: ¿Es accesible en el contexto de su aplicación?
  • Decidir el candidato a actualización 
  • Prueba la nueva imagen:
    • Compilación
    • Ejecuta pruebas unitarias
    • Ejecuta pruebas de integración
  • En caso de fallo, intente parchear el código o actualizar las bibliotecas.
  • Repetir para cada contenedor.

Es agotador.

El coste de la inacción

Podría pensar “si no está roto, no lo arregles.”

Pero los CVE de contenedores sin parchear son un factor que contribuye masivamente a las brechas de seguridad: «El 87% de las imágenes de contenedores en producción tenían al menos una vulnerabilidad crítica o de alta gravedad». fuente 

También existen muchos exploits conocidos en imágenes base populares. 

  • Vulnerabilidad de "Path Traversal" en descompresión (CVE-2020-27350) — permanecieron en millones de contenedores durante años.
  • Heartbleed (CVE-2014-0160) permanecieron en contenedores heredados mucho después de las correcciones oficiales.
  • PHP-FPM RCE (CVE-2019-11043) permiten a los atacantes remotos ejecutar código arbitrario a través de solicitudes HTTP manipuladas y era extremadamente común en imágenes base de contenedores con PHP-FPM preinstalado antes de ser parcheado

Cómo ayuda nuestra función Auto-Fix

Para abordar este escenario específico, Aikido Security lanzó nuestra función de auto-corrección de contenedores porque, bueno, nosotros también experimentamos esta problemática. 

La función opera de la siguiente manera: Aikido escanea sus contenedores en busca de vulnerabilidades. Si (o más probablemente cuando) encontramos vulnerabilidades, como siempre, le alertamos. Luego, en lugar de indicarle que actualice su imagen base, le ofrecemos diferentes opciones. Creamos una tabla que le informa qué versión de la imagen base resolverá qué CVEs, de esta manera puede ver rápidamente que una actualización menor puede eliminar todas o la mayoría de las CVEs de alta criticidad, lo que significa una mejora adecuada de la imagen base. 

Si la actualización es un incremento menor, puedes crear automáticamente una pull request para subir la versión. 

Son horas de trabajo ahorradas

Conclusión:

  • Actualizar las imágenes base de los contenedores es realmente difícil.
  • El consejo de 'simplemente actualizar' simplifica en exceso un proceso complejo y lleno de riesgos.
  • Sus equipos tienen razón al ser cautelosos, pero no deberían tener que elegir entre seguridad y estabilidad.
  • El autofix de contenedores de Aikido hace el trabajo duro por usted para que pueda tomar una decisión informada. 
  • Así que la próxima vez que vea una alerta de vulnerabilidad de imagen base, no entrará en pánico. Recibirá un PR.
4.7/5

Protege tu software ahora.

Empieza gratis
Sin tarjeta
Solicitar una demo
Sus datos no se compartirán · Acceso de solo lectura · No se requiere tarjeta de crédito

Asegúrate ahora.

Proteja su código, la nube y el entorno de ejecución en un único sistema central.
Encuentre y corrija vulnerabilidades de forma rápida y automática.

No se requiere tarjeta de crédito | Resultados del escaneo en 32 segundos.