O token vazou do processo ao lado
Pesquisadores tiraram um JWT de um Cloudflare Worker vizinho a 12 bits por segundo, sem escapar do sandbox e sem nenhum bug de segurança de memória. A fronteira do isolate aguentou. O segredo a atravessou mesmo assim, pelo hardware embaixo. Plataformas de nuvem hoje oferecem essa mesma fronteira para rodar código escrito por agentes de IA. O Bromure Agentic Coding desce uma camada abaixo e mantém suas credenciais inteiramente fora da caixa.
O JavaScript de um inquilino fez algumas milhões de perguntas bem moldadas à CPU e leu, nas respostas, o token de autenticação de outro inquilino. Ele ficou o tempo todo dentro da fronteira que a plataforma desenhou para ele, rodando JavaScript comum, e a fronteira cumpriu seu papel do começo ao fim.
Em 17 de agosto, uma equipe de pesquisadores publicou Remote-Timer-as-a-Service, e no dia 19 a Cloudflare publicou o próprio relato do trabalho. Eles extraíram um JSON Web Token, a string assinada que um serviço aceita como prova de quem você é, de um Cloudflare Worker co-localizado em produção, a até 12 bits por segundo com 99,16% de precisão. O resultado público anterior contra a mesma plataforma, de 2021, chegava a 2 bits por minuto. A 360 vezes essa taxa você cruza a linha entre uma curiosidade e uma credencial roubada.
A Cloudflare corrigiu a falha, não encontrou indício de que mais alguém a tenha usado em três anos e afirma que nenhum dado de cliente foi acessado. Leia além disso e olhe para o que o ataque nunca precisou fazer.
Nada precisou quebrar
O Cloudflare Workers roda muitos inquilinos em pouco hardware, e faz isso dispensando aquilo que costuma separá-los. Nas palavras da própria Cloudflare, o Workers “roda código de múltiplos inquilinos em isolates V8 separados dentro do mesmo processo do sistema operacional”. Um isolate é um contêiner no nível do JavaScript: heap próprio, globais próprios, sem memória compartilhada, sem threads. Ele inicia em milissegundos, e é justamente esse o ponto, porque isolamento por processo custa um cold start a cada requisição.
O atacante precisa de código rodando dentro de um isolate. Colocar a vítima no mesmo
processo é a parte elegante: o Worker do atacante chama a vítima. Como escrevem os
pesquisadores, invocar a vítima a partir do script do atacante com
fetch("https://victim.example") “fará, na maioria dos casos, o escalonador subir
uma instância do worker vítima exatamente no mesmo processo”. Você não espera pela
co-localização, você a convoca.
Daí em diante o ataque é Spectre. Treinar errado um preditor de desvio para que a CPU
execute especulativamente uma leitura que jamais deveria ter feito e então medir a
cache para descobrir o que ela leu. A Cloudflare já havia passado anos tornando isso
difícil: sem SharedArrayBuffer, sem threads, timers congelados e engrossados para
que você não consiga medir nada tão pequeno quanto um acerto de cache, e o Dynamic
Process Isolation (DyPrIs), que observa contadores de desempenho do hardware e move
para um processo próprio qualquer coisa com cheiro de Spectre.
Os pesquisadores contornaram cada uma delas.
O relógio veio de fora. Um WebSocket para um Durable Object, ou para um servidor de timestamp comum na internet, dá resolução de submilissegundo a partir de uma plataforma que se recusa a lhe dar um relógio. Depois eles amplificaram o sinal em vez de resolvê-lo: a política de substituição tree-PLRU da cache L1 segue ponteiros de árvore binária, de modo que um único evento de cache pode virar uma longa sequência de acertos ou uma longa sequência de erros. “O timing de um único evento de cache pode ser arbitrariamente amplificado”, escrevem eles. Um relógio borrado serve se você tornar enorme aquilo que está cronometrando.
O DyPrIs errou duas vezes. Ele isola um script depois que a invocação termina, e um Durable Object mantido vivo por mensagens de keep-alive roda por horas, até um dia inteiro, de modo que o exploit se completa dentro de uma única invocação que nunca acaba. Ele também normaliza os erros de predição de desvio pelos acessos à iTLB enquanto, nas palavras da Cloudflare, “nosso timer remoto é um grande laço de E/S, e esse tráfego WebSocket infla a atividade da iTLB”. Os pesquisadores fizeram o próprio denominador crescer até o alarme marcar normal.
O resto é encanamento: um gadget de confusão de tipos especulativa para vazar o endereço raiz do isolate, confusão de ponteiros de 64 bits sobre o backing store de um typed array para transformar isso numa leitura arbitrária e, então, o JWT da vítima, um bit por vez.
As correções dizem mais que a descoberta
A Cloudflare entregou três mitigações. Leia-as juntas.
Eles integraram o V8 Sandbox, que remove ponteiros brutos de 64 bits da região do heap JavaScript e mata o gadget do typed array. Ensinaram o DyPrIs a tratar Durable Objects de vida longa e cargas pesadas de E/S como casos de segurança de primeira classe, e não como ruído. E implantaram as Memory Protection Keys, colocando o heap de cada inquilino atrás de uma fronteira de acesso imposta pelo hardware dentro do processo compartilhado.
As três descem abaixo do JavaScript atrás de algo mais firme do que a semântica do JavaScript, e a terceira aterrissa na própria CPU. A Cloudflare é franca ao dizer que o V8 Sandbox “não é uma mitigação completa de Spectre”. Engenheiros que consertam uma fronteira no nível da linguagem acrescentando uma fronteira no nível do hardware já lhe disseram onde acham que fica a linha de verdade.
Um blog sobre agentic coding, escrevendo sobre uma CDN
O isolate saiu da CDN. Em março, a Cloudflare lançou os Dynamic Workers sob o título
Sandboxing AI agents, 100x faster,
uma forma de subir um Worker em tempo de execução com código que não existia um
segundo antes. Se você já rodou um agente que escreve e executa os próprios scripts,
conhece a motivação: “se um agente (ou um servidor MCP) vai executar código gerado na
hora por IA para realizar tarefas, esse código precisa rodar em algum lugar”, e “você
não pode simplesmente dar eval() em código gerado por IA direto no seu app”.
A Cloudflare nomeia o mecanismo no mesmo post: “Os Dynamic Workers usam o mesmo mecanismo de sandboxing sobre o qual toda a plataforma Cloudflare Workers foi construída desde seu lançamento, oito anos atrás: isolates.” A velocidade é a razão. Um isolate sobe em poucos milissegundos com poucos megabytes, cerca de 100 vezes mais rápido e de 10 a 100 vezes mais eficiente em memória que um contêiner, de modo que um sandbox novo por requisição fica acessível em vez de um pool morno que você reaproveita e enfraquece a cada turno.
A Cloudflare é aberta sobre o custo. O post de beta deles diz em oito palavras: “Bugs de segurança do V8 são mais comuns que vulnerabilidades de hipervisor.” Eles escreveram isso meses antes de alguém vazar um token.
Então a história aqui é uma troca, escrita pelas próprias pessoas que a fazem, e agora precificada por pesquisadores em 12 bits por segundo. A pergunta cai no colo de todos os outros. Quando o código colocado no sandbox foi escrito por um modelo, moldado por tudo o que um pacote ou uma página web lhe disse, e deixado rodando ao lado de um bearer token, essa é a troca que você quer?
O Bromure traça a linha no hipervisor
O Bromure Agentic Coding não roda seu agente num contêiner no nível da linguagem ao lado do código de outras pessoas. Cada espaço de trabalho é uma máquina virtual Linux sobre o Virtualization.framework da Apple, apenas em Apple Silicon: kernel próprio, memória de convidado própria, disco próprio clonado de uma imagem base somente leitura. Nenhum processo compartilhado significa nenhum co-inquilino para convocar, e a fronteira atrás da qual seu agente roda é o hipervisor, que é o lado da própria comparação da Cloudflare onde os bugs são mais raros.
Essa é a arquitetura. O que teria tornado este ataque em particular inútil é mais estreito, e fica um passo além.
O token nunca esteve na caixa
O que os pesquisadores levaram embora foi um JWT parado no espaço de endereços da vítima, que é onde um serviço em execução guarda a credencial que usa. Eles não conseguiram shell nem root.
Um espaço de trabalho Bromure não guarda a credencial ali.
Todo segredo de um perfil fica no seu Mac. Isso cobre a ANTHROPIC_API_KEY, o token
de acesso pessoal do GitHub, a chave de acesso da AWS, o bearer token do kubeconfig, o
blob de Basic-auth do registro de contêineres e a chave do Linear. O que o Bromure
injeta na VM é falso: um placeholder brm_…, um certificado de cliente descartável,
uma string Basic derivada. O agente lê, o SDK lê, git, kubectl e doctl leem, e o
trabalho passa, porque o proxy MITM no host substitui o valor real na requisição de
saída. A AWS ganha uma volta a mais no parafuso. O host reassina a requisição SigV4
com o material verdadeiro, de modo que qualquer coisa que contorne o proxy recebe de
volta um InvalidSignatureException da Amazon em vez de uma chamada que funciona.
Assim, um atacante com uma leitura arbitrária perfeita dentro dessa VM, a primitiva que os pesquisadores levaram um artigo inteiro para construir, lê um chamariz. Os bytes estão lá, eles parseiam, parecem uma chave e não compram nada fora da máquina. Você tem isso independentemente de a fronteira de isolamento ser impecável ou não, porque o espaço de trabalho está vazio daquilo que vale a pena roubar.
Doze bits por segundo ainda precisam de um caminho de saída
Um canal lateral é metade de uma exfiltração. A outra metade é uma rota para fora, e 12 bits por segundo é uma rota que precisa ficar aberta por um tempo. Um token de 400 caracteres significa minutos de tráfego para um destino que o atacante controla.
Um perfil do Bromure carrega as próprias regras de saída, escritas como uma política
curta no estilo pf e editadas como uma tabela. Seu Mac as aplica, no switch virtual e
no proxy, e nada dentro do convidado tem voz: uma conexão negada recebe um reset, e a
decisão aterrissa como uma linha egress.firewall em Window → Security Timeline
com host, IP, porta e veredito. O código rodando no espaço de trabalho está do lado
errado das regras que precisaria mudar.
Você também pode pôr a mão em cada gasto de uma credencial real. Ligue Require approval to use por segredo: as chaves de API dos modelos, a assinatura SSH, os tokens de GitHub, GitLab e Bitbucket, cada contexto de kubeconfig, DigitalOcean, cada assinatura AWS SigV4, cada registro de contêineres e qualquer regra de token manual que você adicionar. A troca então pausa para um diálogo no macOS, e você a concede por cinco minutos, uma hora ou pela sessão. O convidado nunca chega a responder essa pergunta.
A troca é a história
Isolates são uma boa peça de engenharia, e a Cloudflare lidou com isso do jeito que você gostaria: divulgação coordenada, três mitigações reais, nenhuma conversa mole sobre o que o V8 Sandbox cobre e o que não cobre. Milhões de requisições por segundo não rodam sobre contêineres por um motivo.
Cold starts foram o que venceu a discussão numa CDN, e seu agente de código não está respondendo a uma requisição HTTP em quatro milissegundos. Ele roda por uma hora, instala pacotes que ninguém auditou, executa suítes de teste que um modelo escreveu e lê páginas web que adorariam ter uma conversinha com ele. O que quer que rode essa carga segura seus tokens durante todo o período, e a única coisa que você sabe sobre o código que ele executa é que não foi você quem escreveu.
Para esse trabalho, algumas centenas de milissegundos de boot de VM não são um custo que valha a pena otimizar. A Cloudflare já publicou a taxa de câmbio: bugs do V8 são mais comuns que bugs de hipervisor. O Bromure fica do outro lado dessa troca, e depois tira o token da sala também.
Fontes: 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 março de 2026) · The Hacker News, “Cloudflare Workers Spectre Attack Leaks JWT From Co-Located Worker at 12 Bits/Second” (19 de agosto de 2026)