El token se escapó del proceso de al lado
Unos investigadores sacaron un JWT de un Cloudflare Worker vecino a 12 bits por segundo, sin escapar del sandbox y sin ningún fallo de seguridad de memoria. La frontera del isolate aguantó. El secreto la cruzó igual, por el hardware de debajo. Las plataformas cloud ofrecen hoy esa misma frontera para ejecutar código escrito por agentes de IA. Bromure Agentic Coding baja una capa más y deja tus credenciales completamente fuera de la caja.
El JavaScript de un inquilino le hizo a la CPU unos cuantos millones de preguntas bien formadas y leyó, en las respuestas, el token de autenticación de otro inquilino. Nunca salió de la frontera que la plataforma dibujó para él, corría JavaScript común, y la frontera hizo su trabajo todo el tiempo.
El 17 de agosto un equipo de investigadores publicó Remote-Timer-as-a-Service, y el 19 Cloudflare publicó su propio relato del trabajo. Extrajeron un JSON Web Token, la cadena firmada que un servicio acepta como prueba de quién eres, de un Cloudflare Worker co-localizado en producción, a hasta 12 bits por segundo con un 99,16 % de precisión. El resultado público anterior contra la misma plataforma, de 2021, llegaba a 2 bits por minuto. A 360 veces esa tasa cruzas la línea entre una curiosidad y una credencial robada.
Cloudflare lo ha corregido, no ha encontrado indicios de que nadie más lo usara en tres años y dice que no se accedió a datos de clientes. Lee más allá de eso y mira lo que el ataque nunca tuvo que hacer.
Nada tuvo que romperse
Cloudflare Workers hace correr a muchos inquilinos sobre poco hardware, y lo consigue saltándose lo que suele separarlos. En palabras de la propia Cloudflare, Workers “ejecuta código de múltiples inquilinos en isolates de V8 separados dentro del mismo proceso del sistema operativo”. Un isolate es un contenedor a nivel de JavaScript: su propio heap, sus propias globales, sin memoria compartida, sin hilos. Arranca en milisegundos, y ese es justamente el punto, porque el aislamiento por procesos te cuesta un arranque en frío en cada petición.
El atacante necesita código corriendo dentro de un isolate. Meter a la víctima en el
mismo proceso es la parte elegante: el Worker del atacante llama a la víctima. Como
escriben los investigadores, invocar a la víctima desde el script del atacante con
fetch("https://victim.example") “hará en la mayoría de los casos que el planificador
levante una instancia del worker víctima en exactamente el mismo proceso”. No esperas
la co-localización, la invocas.
A partir de ahí el ataque es Spectre. Entrenar mal un predictor de saltos para que la
CPU ejecute especulativamente una lectura que jamás debió hacer, y luego medir la
caché para averiguar qué leyó. Cloudflare ya llevaba años poniéndolo difícil: sin
SharedArrayBuffer, sin hilos, timers congelados y engrosados para que no puedas
medir nada tan pequeño como un acierto de caché, y Dynamic Process Isolation (DyPrIs),
que vigila los contadores de rendimiento del hardware y mueve a su propio proceso todo
lo que huela a Spectre.
Los investigadores rodearon cada una de esas defensas.
El reloj vino de fuera. Un WebSocket a un Durable Object, o a un servidor de marcas de tiempo cualquiera de internet, te da resolución de submilisegundo desde una plataforma que se niega a darte un reloj. Después amplificaron la señal en lugar de resolverla: la política de reemplazo tree-PLRU de la caché L1 sigue punteros de árbol binario, de modo que un solo evento de caché puede convertirse en una larga serie de aciertos o una larga serie de fallos. “El timing de un único evento de caché puede amplificarse arbitrariamente”, escriben. Un reloj borroso vale si haces enorme aquello que estás cronometrando.
DyPrIs falló por partida doble. Aísla un script después de que la invocación termina, y un Durable Object mantenido vivo con mensajes de keep-alive corre durante horas, hasta un día, así que el exploit se completa dentro de una única invocación que nunca acaba. Además normaliza las predicciones fallidas de salto por accesos a la iTLB mientras, en palabras de Cloudflare, “nuestro timer remoto es un gran bucle de E/S, y ese tráfico WebSocket infla la actividad de la iTLB”. Los investigadores hicieron crecer su propio denominador hasta que la alarma marcó normal.
El resto es fontanería: un gadget de confusión de tipos especulativa para filtrar la dirección raíz del isolate, confusión de punteros de 64 bits sobre el backing store de un typed array para convertir eso en una lectura arbitraria, y luego el JWT de la víctima, un bit cada vez.
Los arreglos dicen más que el hallazgo
Cloudflare entregó tres mitigaciones. Léelas juntas.
Integraron el V8 Sandbox, que saca los punteros crudos de 64 bits de la región del heap de JavaScript y mata el gadget del typed array. Le enseñaron a DyPrIs a tratar los Durable Objects de vida larga y las cargas intensivas en E/S como casos de seguridad de primera clase en lugar de ruido. Y desplegaron las Memory Protection Keys, que ponen el heap de cada inquilino detrás de una frontera de acceso impuesta por hardware dentro del proceso compartido.
Las tres bajan por debajo de JavaScript en busca de algo más firme que la semántica de JavaScript, y la tercera aterriza en la propia CPU. Cloudflare dice con franqueza que el V8 Sandbox “no es una mitigación completa de Spectre”. Unos ingenieros que reparan una frontera a nivel de lenguaje añadiendo una frontera a nivel de hardware ya te han dicho dónde creen que está la línea de verdad.
Un blog de agentic coding escribiendo sobre una CDN
El isolate se ha ido de la CDN. En marzo, Cloudflare lanzó Dynamic Workers bajo el
título
Sandboxing AI agents, 100x faster,
una forma de levantar un Worker en tiempo de ejecución con código que no existía un
segundo antes. Si has hecho correr un agente que escribe y ejecuta sus propios
scripts, conoces la motivación: “si un agente (o un servidor MCP) va a ejecutar código
generado sobre la marcha por una IA para hacer tareas, ese código tiene que correr en
algún sitio”, y “no puedes hacer eval() de código generado por IA directamente en tu
aplicación”.
Cloudflare nombra el mecanismo en ese mismo post: “Los Dynamic Workers usan el mismo mecanismo de sandboxing subyacente sobre el que se ha construido toda la plataforma Cloudflare Workers desde su lanzamiento hace ocho años: isolates.” La razón es la velocidad. Un isolate arranca en unos pocos milisegundos con unos pocos megabytes, unas 100 veces más rápido y de 10 a 100 veces más eficiente en memoria que un contenedor, así que un sandbox nuevo por petición sale asequible en vez de un pool templado que reutilizas y debilitas en cada turno.
Cloudflare es transparente sobre el coste. Su propio post de beta lo dice en ocho palabras: “Los fallos de seguridad de V8 son más comunes que las vulnerabilidades de hipervisor.” Lo escribieron meses antes de que nadie filtrara un token.
Así que la historia aquí es un intercambio, escrito por la propia gente que lo hace, y ahora tasado por unos investigadores en 12 bits por segundo. La pregunta cae sobre todos los demás. Cuando el código que se está aislando lo escribió un modelo, moldeado por lo que un paquete o una página web le contó, y se deja corriendo al lado de un bearer token, ¿es ese el intercambio que quieres?
Bromure traza la línea en el hipervisor
Bromure Agentic Coding no hace correr tu agente en un contenedor a nivel de lenguaje junto al código de otra gente. Cada espacio de trabajo es una máquina virtual Linux sobre el Virtualization.framework de Apple, solo en Apple Silicon: su propio kernel, su propia memoria de invitado, su propio disco clonado de una imagen base de solo lectura. Ningún proceso compartido significa ningún co-inquilino al que convocar, y la frontera detrás de la cual corre tu agente es el hipervisor, que es el lado de la propia comparación de Cloudflare con los fallos más raros.
Esa es la arquitectura. Lo que habría hecho inútil este ataque en concreto es más estrecho, y está un paso más adentro.
El token nunca estuvo en la caja
Lo que los investigadores se llevaron fue un JWT que estaba en el espacio de direcciones de la víctima, que es donde un servicio en ejecución guarda la credencial que usa. No consiguieron ni shell ni root.
Un espacio de trabajo de Bromure no guarda ahí la credencial.
Todos los secretos de un perfil se quedan en tu Mac. Eso cubre la
ANTHROPIC_API_KEY, el token de acceso personal de GitHub, la clave de acceso de AWS,
el bearer token del kubeconfig, el blob de Basic-auth del registro de contenedores y
la clave de Linear. Lo que Bromure inyecta en la VM es falso: un marcador brm_…, un
certificado de cliente desechable, una cadena Basic derivada. El agente lo lee, el SDK
lo lee, git, kubectl y doctl lo leen, y el trabajo sale adelante, porque el
proxy MITM del host sustituye el valor real en la petición saliente. AWS recibe una
vuelta de tuerca extra. El host vuelve a firmar la petición SigV4 con el material
real, así que cualquier cosa que esquive el proxy recibe de Amazon un
InvalidSignatureException en lugar de una llamada que funcione.
Así, un atacante que tenga una lectura arbitraria perfecta dentro de esa VM, la primitiva que los investigadores tardaron un artículo entero en construir, lee un señuelo. Los bytes están ahí, parsean, parecen una clave y no compran nada fuera de la máquina. Eso lo tienes tanto si la frontera de aislamiento es impecable como si no, porque el espacio de trabajo está vacío de aquello que vale la pena robar.
Doce bits por segundo todavía necesitan una salida
Un canal lateral es la mitad de una exfiltración. La otra mitad es una ruta hacia fuera, y 12 bits por segundo es una ruta que tiene que quedarse abierta un rato. Un token de 400 caracteres son minutos de tráfico hacia un destino que el atacante controla.
Un perfil de Bromure lleva sus propias reglas de salida, escritas como una política
corta al estilo pf y editadas como una tabla. Tu Mac las aplica, en el switch virtual
y en el proxy, y nada dentro del invitado tiene voz: una conexión denegada recibe un
reset, y la decisión aterriza como una fila egress.firewall en Window → Security
Timeline con el host, la IP, el puerto y el veredicto. El código que corre en el
espacio de trabajo está del lado equivocado de las reglas que necesitaría cambiar.
También puedes poner la mano en cada gasto de una credencial real. Activa Require approval to use por secreto: las claves de API de los modelos, la firma SSH, los tokens de GitHub, GitLab y Bitbucket, cada contexto de kubeconfig, DigitalOcean, cada firma AWS SigV4, cada registro de contenedores y cualquier regla de token manual que añadas. La sustitución se detiene entonces para un diálogo en macOS, y tú la concedes por cinco minutos, una hora o la sesión. El invitado nunca llega a responder esa pregunta.
El intercambio es la historia
Los isolates son una buena pieza de ingeniería, y Cloudflare ha manejado esto como querrías: divulgación coordinada, tres mitigaciones reales, ningún baile alrededor de lo que el V8 Sandbox cubre y lo que no. Millones de peticiones por segundo no corren sobre contenedores por algo.
Los arranques en frío son lo que ganó la discusión en una CDN, y tu agente de código no está respondiendo una petición HTTP en cuatro milisegundos. Corre durante una hora, instala paquetes que nadie ha auditado, ejecuta suites de tests que escribió un modelo y lee páginas web a las que les encantaría cruzar unas palabras con él. Lo que sea que ejecute esa carga sostiene tus tokens todo ese tiempo, y lo único que sabes del código que corre es que no lo escribiste tú.
Para ese trabajo, unos cientos de milisegundos de arranque de VM no son un coste que merezca la pena optimizar. Cloudflare ya publicó el tipo de cambio: los fallos de V8 son más comunes que los de hipervisor. Bromure se pone en el otro lado de ese intercambio, y además saca el token de la habitación.
Fuentes: Schwarzl, Xiao, Pedersen, Ainsworth, Topham, “Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers” (arXiv:2608.17043, 17 de agosto de 2026) · Cloudflare, “A revisit of remote Spectre attacks on Cloudflare Workers” (19 de agosto de 2026) · Cloudflare, “Sandboxing AI agents, 100x faster” (24 de marzo de 2026) · The Hacker News, “Cloudflare Workers Spectre Attack Leaks JWT From Co-Located Worker at 12 Bits/Second” (19 de agosto de 2026)