Seguridad

Cloudflare Containers: vulnerabilidad cross-tenant expone datos de usuarios Linux en dm-thin

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30 minutos a 2 horas dependiendo de la complejidad del entorno.
  • Requisitos: Acceso root, Linux moderno, conexión a internet para descargar dependencias.
  • Resultado: Servicio funcional y estable, documentado paso a paso.
  • Troubleshooting: Logs estándar en /var/log/, comandos de verificación al final de cada sección.

Lo que pasó realmente

El 25 de septiembre de 2026 Cloudflare confirmó haber parcheado una vulnerabilidad en Cloudflare Containers y Cloudflare Sandboxes que permitía a un cliente con cuenta Workers Paid leer bloques de disco residuales que otros clientes habían dejado atrás en servidores físicos compartidos. El aviso vino acompañado de un reporte técnico publicado en el blog oficial de Cloudflare, firmado en conjunto con el equipo de investigación de Accomplish, que fue quien reportó el fallo a través del programa de bug bounty en HackerOne.

Lo delicado del asunto no es el vector en sí: el atacante no podía elegir a qué cliente, host ni contenedor apuntar. Lo delicado es el tipo de dato que se quedó expuesto sin protección entre tenants: directorios ext4 completos, páginas de SQLite, bases de datos estructuralmente legibles, perfiles de Chromium, archivos .env y credenciales. Cualquier cliente con un plan Workers Paid podía, en la práctica, abrir la raíz de su contenedor (/dev/vdc), identificar regiones libres de 64 KiB alineadas con la free space del filesystem invitado y forzar a dm-thin a entregar bloques físicos previamente usados por otro tenant. Si el bloque no estaba zeroed, los 60 KiB restantes del bloque quedaban legibles.

La causa raíz: skip_block_zeroing en dm-thin

Cloudflare Containers corre cada carga de trabajo dentro de una microVM gestionada por Firecracker, el mismo monitor de máquinas virtuales que usa Lambda y otros servicios serverless de AWS. Cada contenedor recibe un disco raíz virtual expuesto como /dev/vdc, respaldado por device mapper thin provisioning del kernel Linux. dm-thin asigna bloques físicos sólo cuando el invitado escribe sobre una región previamente no mapeada.

El detalle que rompió el aislamiento multi-tenant fue una opción de configuración llamada skip_block_zeroing. Con esa opción activa, dm-thin no limpiaba los bloques nuevos antes de entregarlos al contenedor siguiente. En el pool afectado, el tamaño de bloque era 64 KiB. Cuando un contenedor escribía sólo 4 KiB sobre un bloque recién asignado, los 60 KiB restantes mantenían los datos del dueño anterior del bloque físico.

Es un bug de capa de almacenamiento, no de virtualización ni de orquestación. Firecracker cumplió su contrato de aislamiento: cada VM tiene su propio thin volume y no comparte dispositivos con otras VMs. El problema estaba en cómo el pool físico, compartido entre muchas VMs, trataba los bloques devueltos al pool cuando un thin volume se borraba. Cloudflare retiró skip_block_zeroing del pool afectado, restaurando el comportamiento por defecto de dm-thin de limpiar los bloques nuevos antes de exponerlos.

El proof-of-concept de Accomplish, en pasos

El equipo de Accomplish construyó un PoC reproducible que Cloudflare validó y reprodujo internamente. Los pasos están en el blog oficial y vale la pena entenderlos porque muestran el alcance real:

# Paso 1: crear un contenedor con una cuenta Workers Paid
npx wrangler containers deploy poc-app
# Paso 2: dentro del contenedor, abrir el disco raíz raw
# (esto NO requiere privilegios especiales dentro de la VM)
dd if=/dev/vdc of=/tmp/baseline.bin bs=64K count=1024
# Paso 3: identificar regiones de 64 KiB alineadas con free space ext4
# (Accomplish usó los chequeos de metadata_csum de ext4)
# Paso 4: escribir UN solo bloque de 4 KiB en cada región seleccionada
# (disparar la asignación de un bloque físico nuevo en dm-thin)
dd if=/dev/urandom of=/dev/vdc bs=4K count=1 seek=
# Paso 5: releer la misma región
dd if=/dev/vdc of=/tmp/residual.bin bs=64K count=1 skip=
# → hasta 60 KiB pueden contener datos del tenant anterior

Lo importante del PoC es que no necesitas acceso root ni capacidades especiales dentro de tu propia VM: leer /dev/vdc desde un proceso sin privilegios basta, porque Linux entrega el device node con permisos por defecto dentro del contenedor. Tampoco hace falta abusar de ninguna syscall fuera de lo normal: dd estándar alcanza. La detección se basó en checksums de bloques de directorio de ext4 con metadata_csum activo, lo que permitió atribuir cada bloque a su filesystem de origen.

Alcance medido en producción

El reporte de Accomplish (que se hizo público después de la remediación) incluye números concretos que ayudan a dimensionar la falla:

  • 5,614 bloques de directorio testeados a través de 6 placements en producción, todos atribuibles a tenants distintos del atacante.
  • 2,700 inodos de directorio extranjeros distintos identificados por checksum.
  • Material residual observable en 18 de 24 placements probados.
  • Cobertura geográfica: 20 de 22 nodos subyacentes en cuatro continentes.
  • Tipos de bloque recuperado: estructuras de directorio, páginas de bases de datos y SQLites estructuralmente completos.

Cloudflare verificó los mismos hallazgos en su flota. El detalle clave es que el método no apunta: no puedes elegir leer la base de datos de un cliente específico. Lo que puedes hacer es leer lo que dm-thin te asigne por azar en tu pool, lo cual sigue siendo un compromiso de aislamiento importante porque tu contenedor puede terminar con material que otro cliente cree haber borrado.

Lo que Cloudflare cambió (y lo que no)

La mitigación se hizo en dos fases, ambas sin acción requerida del cliente:

  1. Remover skip_block_zeroing del pool dm-thin en toda la flota de Containers. Esto detiene la técnica del write pequeño + read grande a partir de la fecha del merge.
  2. Invalidar caches de snapshots y reiniciar VMs existentes. Zeroear bloques nuevos no limpia los bloques ya mapeados en volúmenes pre-existentes, ni los snapshots cacheados de imágenes OCI. Cloudflare drenó hosts en horario valle, reinició las VMs y limpió caches de imagen en cada nodo. Esto se completó el 19 de septiembre de 2026.

Cloudflare revisó telemetría histórica de I/O de disco usando como firma la relación 4 KiB write + lectura mayor (60 KiB de residual), y concluyó que no hay evidencia de explotación por terceros. La única actividad consistente con la técnica viene de los investigadores de Accomplish y de los ingenieros de Cloudflare que reprodujeron el bug internamente.

El reporte HackerOne es público: HackerOne #3997565. El blog oficial está en blog.cloudflare.com/containers-cross-tenant-vulnerability. El análisis técnico de Accomplish, con detalles del método de checksums de ext4, está en accomplish.ai/blog/escaping-the-cloudflare-sandbox.

Timeline completa

Fecha (UTC) Hito
4-sep 15:26 Oren Yomtov (Accomplish) reporta el bug vía HackerOne
4-sep 18:45 Cloudflare abre incidente de seguridad y confirma el setup que causaba el fallo
4-sep 21:27 Merge del fix en runtime + test de reuse
4-sep 22:03 Merge del cambio para pools nuevos y pools live
4-sep 23:15 Inicio del rollout a la flota
7-sep 06:13 Rollout completo, comienza limpieza de datos viejos
14-sep 10:50 Investigadores confirman que su PoC ya no funciona
14-sep 12:52 Cloudflare otorga bounty al investigador
19-sep 15:03 Cleanup completo de snapshots pre-mitigación en toda la flota
25-sep Publicación coordinada del blog de Cloudflare y el reporte de Accomplish

Por qué importa si no usas Cloudflare Containers

Aunque no ejecutes Containers, este incidente deja tres lecciones generales para cualquiera que opere infraestructura multi-tenant o planee hacerlo:

  • El default seguro en storage pasa por zeroing, no por skip. dm-thin, thinLVM y cualquier pool con thin provisioning comparte este patrón: si saltas el zeroing por performance, abres una ventana de cross-tenant leakage. El costo de zeroear bloques nuevos es medible pero acotado; el costo de no hacerlo, mucho más alto si se descubre.
  • Caches de snapshots son parte del ataque. La segunda fase de mitigación de Cloudflare (invalidar caches OCI) muestra que zeroear bloques nuevos no limpia snapshots pre-existentes que ya tienen mappings. Si tu stack usa overlayfs, lvms thin, o cualquier layer con cache, revisa qué pasa cuando reasignas un bloque que ya está mapeado en una capa anterior.
  • El aislamiento por VM no es lo mismo que el aislamiento por bloque físico. Firecracker garantiza que cada VM ve su propio device. Pero todos comparten el pool físico de dm-thin. Si tu pool trata bloques reasignados sin zeroing, el aislamiento de VM no te protege. Esto es relevante si usas Firecracker, Cloud Hypervisor, QEMU con thin backing, o cualquier runtime serverless sobre kvm.

Qué deberías mirar en tu propio stack

Si administras servidores Linux con pools thin-provisioned (LVM thin, dm-thin directo, Ceph con backend raw, ZFS con sparse volumes), tres controles rápidos que valen la pena:

# 1. Verificar configuración de tu pool LVM thin
lvs -o+lv_options vg0/data_pool
# Buscar 'skip_block_zeroing=1'. Si está, cambiá a 0.
# 2. Confirmar el comportamiento por defecto del kernel (5.15+ ya es seguro)
cat /sys/module/dm_thin/parameters/skip_block_zeroing_default
# Esperado: N
# 3. Para Firecracker, auditar el JSON de microVM
grep -E 'block|drives' /var/lib/fc/vm.json | head -10
# Confirmá que el backing store no hereda snapshots pre-mitigación

Si encuentras skip_block_zeroing activo, la remediación es un cambio de configuración + recreate del pool. No requiere tocar el filesystem invitado ni las VMs. Eso sí: planifica el mantenimiento porque recrear el pool implica mover o copiar los thin volumes existentes.

Qué cambió en tu superficie de ataque

Si usas Cloudflare Containers o Sandboxes como proveedor, no tienes que hacer nada del lado del cliente: la mitigación está aplicada y Cloudflare ya completó la limpieza de snapshots pre-mitigación en toda la flota. Si tienes cargas con datos sensibles (claves, tokens, material de clientes), considera rotar credenciales y material de configuración que estuvo dentro de Containers antes del 19 de septiembre, porque no se puede descartar al 100% que un atacante con acceso a Workers Paid haya podido recuperar algo en el período vulnerable. Cloudflare dice no tener evidencia de explotación, pero la palabra “evidencia” acá significa “telemetría retrospectiva”, no “certeza lógica”.

Para Sandboxes específicamente, ten en cuenta que la base de Sandboxes es Containers, así que el alcance del bug aplica igual. Si dependes de Sandboxes para ejecutar código generado por IA, código de terceros, o cargas con datos sensibles, este es un buen momento para revisar qué se queda en /dev/vdc entre ejecuciones y cuánto confías en que la capa de storage limpie esos residuos.

Resumen

Cloudflare parchó en 6 días un fallo de configuración de dm-thin (skip_block_zeroing) que permitía a un cliente Workers Paid leer bloques residuales de otros tenants en Cloudflare Containers y Sandboxes. La técnica era accesible con dd estándar sobre /dev/vdc, no requería privilegios especiales y los investigadores recuperaron hasta 60 KiB por cada 4 KiB escrito. El alcance medido fue significativo: 18 de 24 placements, 20 de 22 nodos, cuatro continentes. Cloudflare no encontró evidencia de explotación por terceros.

Las lecciones generales son tres: zeroear bloques nuevos es el default seguro, los caches de snapshots siguen siendo superficie de ataque después del fix, y el aislamiento de VM no protege contra fallos en la capa de storage compartida. Si operas pools thin-provisioned propios, auditar skip_block_zeroing es un control barato que vale la pena agregar a tu checklist.

Preguntas frecuentes

¿Por qué Cloudflare Containers: vulnerabilidad cross-tenant expone datos de usuarios Linux en dm-thin es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Cloudflare Containers: vulnerabilidad cross-tenant expone?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Cloudflare Containers: vulnerabilidad cross-tenant expone?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Cloudflare Containers: vulnerabilidad cross-tenant expone y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Cloudflare Containers: vulnerabilidad cross-tenant expone?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *