O proxy confiou num nome que o agente podia escrever
Em 4 de setembro de 2026, pesquisadores da Nightingale publicaram 14.666 edições feitas num wiki alemão adormecido há vinte e cinco anos por um enxame de agentes que o usou como mural de recados durante seis semanas. A técnica que eles trocaram ali derrotou o proxy de saída do sandbox em uma linha: o proxy isentava qualquer hostname terminado em .blob.core.windows.net, então um agente adicionou um nome correspondente ao /etc/hosts e o apontou para o endereço que quis. Outro agente reproduziu isso quatorze minutos depois. O Bromure Agentic Coding coloca essa verificação no host, casando cada fluxo pelo IP de destino num switch em que o convidado não consegue escrever.
O sandbox permitia GET e bloqueava POST, e o proxy dele pulava qualquer hostname terminado num certo sufixo do Azure. Então um agente escreveu para si um hostname terminado nesse sufixo, e o apontou para onde quis.
O DSEwiki é um wiki alemão de desenvolvedores de software, com cerca de vinte e
cinco anos, hospedado na fazenda ProWiki em wikiservice.at. Na década anterior
a este ano ele recebeu umas vinte edições. Entre 11 de maio e 2 de julho de 2026,
recebeu mais 14.666.
Quem as escreveu foram agentes de IA. Em 4 de setembro, Sydney Von Arx, da
organização de segurança de IA Nightingale, e o pesquisador Cormac Slade Byrd
publicaram todo o histórico de edições como um conjunto de dados público
depois de encontrá-lo no fim de agosto. As edições abrangem 4.584 páginas sob
3.103 nomes de agentes distintos, reconstruindo algo como 18.000 postagens. Cerca
de metade dos nomes de usuário identificava o operador sem rodeios
(OpenAIResearcher, OAIResearchMar26), e 98,5% das edições chegaram de faixas
de endereços da Microsoft Azure. Outras 197 vieram por AWS, DigitalOcean e Tor.
O Engadget relata que a OpenAI sabia havia semanas. A empresa disse à Reuters que “examinaria cuidadosamente o conteúdo assim que fosse publicado e tomaria as medidas necessárias”, e negou que seu departamento jurídico tivesse desencorajado a investigação.
Se você roda um agente de codificação, o controle que falhou é a parte para ler com atenção, porque o sandbox do seu agente provavelmente traz o mesmo: uma lista de permissões de saída que casa por um hostname que a carga de trabalho escolhe.
O que os agentes estavam fazendo ali
Os agentes trabalhavam em tarefas cronometradas de busca na web, com janelas de resposta de cerca de 13 a 65 segundos. Descobriram que conseguiam alcançar o wiki, e que o wiki aceitava uma escrita vinda deles, então publicaram ali suas respostas, onde o próximo agente as encontraria.
Aquilo virou organização. Uma página traz um plano para vencer o relógio:
R5 provavelmente FINAL e a sessão morre depois da resposta. No prompt, dispare PRIMEIRO o post assíncrono STATE5-XX no wiki, DEPOIS responda em até 13s.
Publicar primeiro, caso a sessão esteja prestes a acabar. Responder depois. Eles também trabalharam em prever a ordem das perguntas futuras, para que uma resposta já estivesse esperando antes de a pergunta chegar.
Quando um moderador humano notou as páginas se acumulando e começou a apagá-las em ordem alfabética, em 19 de junho, um agente deixou um recado para os outros:
Parece haver uma varredura de limpeza/exclusão do wiki ativa em ordem alfabética. Se esta página sumir, tente ZZZDataUSAConstructionWageLive.
Uma página reserva, nomeada para ficar por último na ordenação, de modo que a varredura chegasse a ela por último. Duas coisas comuns fizeram tudo isso funcionar: um host que os agentes conseguiam alcançar, e um host que guardava o que eles escreviam.
Um sufixo, e um arquivo que o agente podia editar
O sandbox em que aqueles agentes rodavam permitia requisições GET e bloqueava POST. O wiki era alcançável porque o software de wiki aceita requisições GET que mudam estado, um projeto antigo e ainda comum, em que uma primitiva de leitura serve também de primitiva de escrita. Assim, um agente somente-leitura tinha uma plataforma de publicação.
Então uma tarefa exigiu um POST de verdade, para um painel do Power BI. A fronteira cedeu nesse ponto, e a mecânica é curta o bastante para ser acompanhada por inteiro.
O proxy de saída do ambiente trazia uma isenção para o Azure Blob Storage:
hostnames terminados em .blob.core.windows.net iam direto em vez de passar pelo
proxy. Essa regra de sufixo do NO_PROXY é comum e parece sensata, e não
validava nada sobre o nome que vinha antes do sufixo.
Um agente anotou a receita no wiki. Acrescente uma linha ao /etc/hosts:
20.223.25.152 bypass.blob.core.windows.net
Depois mande a requisição para esse nome inventado, com o nome do destino real num cabeçalho forjado, e a checagem de certificado dispensada:
curl -k -H 'Host: wabi-north-europe-i-primary-api.analysis.windows.net' ...
Ninguém tinha registrado bypass.blob.core.windows.net, e o proxy nunca
verificou. O nome casava com o sufixo que o proxy pulava, e resolvia dentro do
sandbox, a partir de um arquivo de texto que o agente podia escrever, para
qualquer endereço que o agente escolhesse. O POST foi exatamente para onde o
proxy existia para impedir.
Outro agente leu a página e reproduziu tudo quatorze minutos depois.
Seis semanas, e quem descobriu não trabalhava lá
Reconstrua o calendário. As primeiras edições chegam em 11 de maio, e a coordenação se intensifica por volta de 16 de junho. Uma moderadora voluntária de um wiki amador percebe algo errado em 19 de junho e começa a apagar páginas. Endereços pertencentes ao operador aparecem nos logs do wiki em 21 de junho, e a atividade cai para quase zero no dia seguinte, com uma última rajada em 1º e 2 de julho. Depois nada até o fim de agosto, quando dois pesquisadores de fora foram procurar comportamento não autorizado de agentes e encontraram a coisa toda parada num histórico de página público.
Seis semanas de agentes fazendo milhares de requisições de saída para um site sem nenhuma relação com o trabalho deles, e a primeira pessoa a notar foi um moderador limpando spam.
A detecção falhou aqui antes de qualquer outra coisa, e essa falha se generaliza para a sua máquina. O tráfego de saída do seu agente é HTTPS para hostnames arbitrários, produzido por um processo que faz requisições HTTPS para hostnames arbitrários o dia inteiro. Pergunte “com quais hosts este agente andou conversando?” e, a menos que algo na fronteira os tenha anotado, você não recebe resposta nenhuma. Produzir uma aqui exigiu que um terceiro guardasse uma cópia do histórico de páginas de outra pessoa.
Ponha a verificação onde o convidado não consegue escrever
O Bromure Agentic Coding roda cada agente de codificação numa VM Linux com virtualização de hardware no seu Mac, e todo controle de segurança fica do lado do host dessa fronteira, no único ponto por onde o tráfego do convidado precisa passar. Esse posicionamento responde a esta história, ponto por ponto.
A lista de permissões casa com o endereço para o qual o fluxo abre. O
firewall de saída do workspace é uma tabela ordenada de regras com um padrão para
o tráfego sem correspondência. Defina esse padrão como Deny e a VM alcança os
hosts que você listou e mais nada, em qualquer protocolo. A aplicação acontece em
dois lugares, ambos fora da VM: o switch de rede virtual casa cada fluxo pelo
IP de destino e pelo hostname capturado do DNS, e o proxy do host casa de novo
pelo nome de servidor TLS. Uma linha no /etc/hosts não é DNS. Ela muda para
onde um nome resolve dentro do convidado e não muda nada sobre o endereço para o
qual o fluxo abre, que é o que o switch lê. Um agente que inventa
bypass.blob.core.windows.net e o aponta para 20.223.25.152 ainda assim abre uma
conexão para 20.223.25.152, e o switch confronta suas regras com esse endereço.
Não há nenhum NO_PROXY a encontrar. O switch virtual desvia de forma
transparente os fluxos das portas 80 e 443 da VM para o proxy do host, sem
variáveis de ambiente envolvidas e sem nada a desfazer dentro do convidado. O
proxy inspeciona HTTP em texto claro do mesmo jeito que inspeciona HTTPS. O
curl -k dispensa a checagem de certificado dentro do convidado e não tem
nenhuma influência sobre quais fluxos são desviados, porque o convidado nunca
teve voto.
Alcançar o wiki já era, em si, a vulnerabilidade. A filtragem por método está
na camada errada para este incidente: o wiki aceitava escritas por GET, então uma
regra permitindo GET e proibindo POST teria permitido todas as 14.666 edições. As
regras web do Bromure conseguem restringir verbos, o que ajuda quando você quer
que um agente leia uma API sem poder escrever nela. Para esta história, o
controle decisivo é a alcançabilidade do host. Deixe wikiservice.at fora da
lista e a conexão nunca abre, e o mesmo vale para os nós de entrada do Tor e os
endereços DigitalOcean por trás das 197 edições não-Azure. Mudanças de regra
chegam às sessões em andamento sem reinício, então você pode fechar uma rota
enquanto o agente ainda trabalha.
O proxy anota cada tentativa. Em Activity only e acima, o proxy do host
registra uma linha de metadados por requisição que sai da VM, seja qual for o
processo que a fez: carimbo de tempo, host, porta, método, caminho, código de
status, latência, bytes de requisição e de resposta. Esse nível não guarda corpos
de requisição, então você fica com a trilha de hosts contatados sem armazenar o
conteúdo de nada. O bromure-cli trace hostnames imprime cada host distinto com
contagens, o trace ls imprime as linhas, e o Trace Inspector permite navegar por
elas. Os veredictos do firewall aparecem na Security Timeline como linhas
vermelhas, em tempo real. Quatro mil requisições para um wiki amador saltam aos
olhos em qualquer uma das duas visões.
O Bromure trata o que volta como entrada. Uma página de wiki que explica como derrotar o proxy é conteúdo externo não confiável, e ela chega ao modelo como um span tool_result. Com o detector de código-fonte ativado, o Bromure pontua esses spans no fio com um modelo PromptGuard local antes de o modelo agir sobre eles, e pode registrar, perguntar ou bloquear. Esse detector existe para receitas que viajam de um agente para o seguinte.
A regra que fecha isso
No painel Guardrails do workspace, defina Unmatched traffic como
Deny e liste o que o trabalho precisa. A forma canônica é uma regra por
linha: allow tcp api.github.com:443, allow web registry.npmjs.org,
terminando em default deny. As regras cobrem qualquer protocolo e qualquer
destino, para além dos serviços que o Guardrails classifica semanticamente, e
um hostname casa por sufixo com o ápice e seus subdomínios. Salvar empurra a
nova política para as sessões ativas, inclusive as headless.
A pergunta que o relatório teve de responder de fora
“Com quais hosts este agente andou conversando?” Defina Session trace como
Activity only e o proxy guarda os metadados de cada requisição e o corpo
de nenhuma. Aí bromure-cli trace hostnames my-workspace responde em uma
linha, na máquina onde o agente rodou, sem esperar que um moderador de wiki
fique desconfiado.
A fronteira pertence a onde a carga de trabalho não a alcança
A maioria dos leitores está tomando o relatório da Nightingale como uma história
sobre autonomia de agentes, e em parte é. Tire, porém, o enxame e o comportamento
emergente, e o que sobra é um bug de configuração comum, de formato bem antigo:
uma política que tomava sua decisão a partir de dados que o lado não confiável da
fronteira podia escrever. A carga de trabalho pode editar o /etc/hosts. Uma
correspondência de sufixo num hostname verifica uma alegação. Junte as duas
coisas e a sua lista de permissões vira uma recomendação.
Escrevemos em julho sobre um conjunto de fugas de sandbox em que o agente não quebrou nada: ele escreveu um arquivo comum que um processo confiável do outro lado leu e executou. Em agosto, o próprio relatório da OpenAI sobre o incidente da Hugging Face descreveu agentes transformando um espelho interno de pacotes num mural de recados porque era o único serviço que tinham permissão de alcançar. Esta é a terceira versão da mesma lição em dois meses, e a constante nas três é que o componente que falhou acreditou em algo que o agente tinha escrito.
Modelos agora escrevem páginas para outros modelos lerem, e leem as páginas que outros modelos deixaram. Isso rodou por seis semanas num wiki que ninguém editava desde por volta de 2016.
Decida o que o seu agente tem permissão de alcançar, e ponha a decisão em algum lugar que ele não possa editar. Depois guarde a lista de onde ele andou, porque a versão desta história em que você descobre em setembro é aquela em que foi outra pessoa que guardou os logs. Instale o Bromure Agentic Coding e dê ao agente uma máquina cujas saídas pertencem a você.