¿Los contenedores siguen siendo un límite de seguridad?
Un malware corriendo dentro de un contenedor puede explotar un bug del kernel, escalar a root y, de repente, está en el host. El límite del contenedor se vuelve decorativo.
¿Los contenedores siguen siendo un límite de seguridad? Imagen generada con Google Gemini
Durante años, los contenedores se han vendido como "aislamiento liviano": empaqueta tu app, córrela en cualquier lado y duerme tranquilo porque el código malicioso no puede tocar el host. Esa historia es mayormente cierta—hasta que el kernel decide tener un mal día. Con una seguidilla constante de CVEs del kernel de Linux y bugs de escalada de privilegios local (LPE), es razonable preguntarse: ¿sigue siendo un contenedor un límite de seguridad significativo, o solo un chroot muy confiado con presupuesto de marketing?
Cómo aíslan los contenedores en realidad
Cuando ejecutas docker run, no estás arrancando un SO diminuto. Estás llamando a clone(2) con un montón de flags. El kernel crea un proceso hijo con nuevos namespaces: mount, PID, user, network, IPC, UTS y cgroup. Obtienes un sistema de archivos raíz falso, un usuario root falso y una red falsa. Se siente como una VM. No lo es.
Bajo el capó, runc (u otro runtime OCI) usa flags como CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUSER y CLONE_NEWNET. El PID 1 del contenedor no es más que un proceso en el host, oculto por un namespace de PID. Su usuario root a menudo se mapea a un UID sin privilegios mediante un namespace de usuario. Su /etc es un namespace de montaje. Todo es truco del kernel. Cada syscall sigue llegando al mismo kernel del host.
Ese kernel compartido es la gracia. También es el problema.
El kernel es el límite
El kernel media todo: archivos, memoria, red, dispositivos. La interfaz de syscalls no es privilegiada; cualquier proceso puede llamar a open, read, write, splice, io_uring y amigos. Se supone que el kernel verifica permisos y te mantiene en tu carril. Si un bug te permite confundir al kernel, puedes salirte de ese carril y llegar a root.
Dirty COW (CVE-2016-5195) fue la llamada de atención: una race condition en copy-on-write permitía escalada de privilegios local universal. En ese entonces, un bug de ese tamaño se sentía como un evento anual. Parcheabas, seguías adelante y rezabas para que nadie posea un zero-day.
Ahora, la investigación de vulnerabilidades asistida por IA ha puesto ese modelo patas arriba. LPEs recientes reportadas con nombres como Copy Fail y Dirty Frag muestran sobrescrituras de page-cache y bugs de socket splicing que pueden convertir un escape de contenedor en una toma de control del host. Los nombres son ridículos; el impacto no. Un malware corriendo dentro de un contenedor puede explotar un bug del kernel, escalar a root y, de repente, está en el host. El límite del contenedor se vuelve decorativo.
El gráfico de CVEs del kernel no va a la baja. Si ejecutas código no confiable en un contenedor común, estás compitiendo contra el ciclo de parches. A veces ganas. A veces gana el atacante. Como argumenta el análisis reciente de Depth First, el límite del contenedor ya no es algo con lo que puedas contar.
Kubernetes no cambia la matemática
Kubernetes orquesta contenedores. No agrega aislamiento por hardware. Programa pods en nodos, y esos pods comparten un kernel. La multi-tenencia sobre el mismo kernel es una decisión de confianza. Si los inquilinos ejecutan código arbitrario, un exploit del kernel puede comprometer el nodo y todos los contenedores que están en él.
Por esto los proveedores de nube a menudo aíslan a los inquilinos a nivel de VM, no solo a nivel de contenedor. También es por esto que las plataformas serverless y las ofertas de Kubernetes administrado suelen usar microVMs o runtimes sandboxeados bajo el capó. Kubernetes es un gran orquestador. No es un límite de seguridad.
MicroVMs: devolviendo el hardware al juego
Una microVM es una máquina virtual real, solo que pequeña y rápida. Usa un VMM (Virtual Machine Monitor) como Firecracker o Cloud Hypervisor, que habla con KVM. La CPU impone el aislamiento de memoria. Un guest comprometido no puede tocar el host a menos que el atacante encuentre un bug del hipervisor.
Esa es una superficie de ataque mucho más pequeña que todo el kernel de Linux. KVM no es invencible —el KVM CTF de Google ha pagado grandes recompensas por escapes—pero la tasa de bugs es órdenes de magnitud menor que la de LPEs del kernel. Proyectos como Firecracker (usado por AWS Lambda y Fargate), Kata Containers y gVisor (un kernel en espacio de usuario que intercepta syscalls) ofrecen un aislamiento más fuerte para cargas de trabajo no confiables.
Enfoque
Mecanismo de aislamiento
Superficie de ataque
Uso típico
Contenedores
Namespaces + cgroups
Kernel del host
Cargas de trabajo confiables, empaquetado
MicroVMs
Virtualización por hardware (KVM)
Hipervisor + VMM
Código multitenant no confiable
gVisor
Kernel en espacio de usuario
Superficie de syscalls de gVisor
Sandboxing, serverless
Qué hacer si ejecutas código no confiable
Si tu modelo de amenaza incluye código malicioso, los contenedores por sí solos no son suficientes. Aquí tienes una lista práctica:
Usa microVMs o runtimes en sandbox para cargas de trabajo multi-tenant o no confiables.
En Kubernetes, usa RuntimeClass para seleccionar Kata Containers, Firecracker o gVisor para pods sensibles.
Aplica hardening en los contenedores de todas formas: quita capabilities, habilita seccomp, AppArmor/SELinux, rootfs de solo lectura y ejecuta como non-root.
Separa zonas de confianza: nodos distintos para inquilinos distintos.
Aplica parches a los kernels rápido, pero no confíes en ganar la carrera.
Monitorea CVEs y ten un plan de respuesta a incidentes que asuma que el escape es posible.
Los contenedores siguen siendo excelentes para empaquetado, densidad y orquestación. No son un límite de seguridad fuerte contra exploits del kernel. Si necesitas un límite, pon un hipervisor o un kernel en espacio de usuario en el medio. El kernel es código. El código tiene bugs. La IA los está encontrando más rápido. Elige tus límites en consecuencia.
Los proveedores de nube construyen infraestructura física impresionante y resiliente, pero no pueden hacer que la geopolítica o la física sean irrelevantes. Una región puede caerse por horas, meses o para siempre. Tu arquitectura debería asumir esa posibilidad y ubicar los datos en consecuencia.
En ciberseguridad no se compite, se colabora. La propuesta de Vulnerable.cl —hecha en Chile y liberada para la comunidad— va en esa línea: una herramienta gratuita que respeta la privacidad de tu configuración y te entrega una revisión rápida de hardening.