O guarda e o shell discordaram
Em 30 de junho, a Adversa AI divulgou o GuardFall — uma classe de contornos que faz passar truques de bash com décadas de idade direto pelos guardas de comando embutidos em 10 dos 11 agentes de código open source mais populares. A razão é simples e impossível de corrigir nessa camada: o guarda lê o texto, e o bash reescreve o texto antes de executá-lo. O Bromure Agentic Coding nunca apostou que o guarda leria o bash corretamente. Apostou que o comando não importa no momento em que é executado.
O filtro de segurança de um agente de código olhou para a string
r''m -rf ~ e viu um comando que não reconheceu, então deixou passar.
O bash olhou para a mesma string, jogou fora as aspas vazias e executou
rm -rf ~. O filtro e o shell estavam lendo duas linguagens diferentes.
Essa lacuna não é um bug em uma ferramenta — é a ideia inteira de
guardar um agente por correspondência de padrões nos comandos que ele
digita, e a Adversa AI acabou de mostrar que ela falha em dez dos onze
agentes que testou.
O guarda de comandos é o recurso ao qual toda ferramenta de código
agêntico recorre primeiro. O agente propõe um comando de shell; um filtro
inspeciona a string; se parecer destrutiva — rm -rf, um curl … | sh
via pipe, um dd para um dispositivo bruto — o guarda a bloqueia ou pede
sua confirmação. É a coisa que permite ligar a execução automática e se
sentir seguro. Em 30 de junho de 2026, a Adversa
AI
publicou uma pesquisa, retomada por The Hacker
News
e SecurityWeek,
mostrando que o recurso é teatro.
O que é o GuardFall
Eles o chamam de GuardFall, e não é um CVE. Não há nada para corrigir, porque não é uma falha em um componente — é uma incompatibilidade entre dois deles. Nas palavras da Adversa: "Um guarda inspeciona texto bruto, enquanto o shell do sistema (bash) expande, remove aspas e reescreve o texto antes de executá-lo." O filtro corresponde à string que o modelo emitiu. O bash então passa essa string por remoção de aspas, expansão de variáveis e substituição de comandos antes que um único byte seja executado. Os dois nunca olham para o mesmo comando, então qualquer truque que sobrevive à reescrita mas não à correspondência passa sem obstáculos.
Esses truques são mais antigos do que a maioria das pessoas que usam os agentes. A Adversa os agrupou em cinco classes:
- Remoção de aspas.
r''msão dois tokens para uma regex e a palavrarmpara o bash, que descarta as aspas vazias. - Expansão de variáveis.
rm$IFS-rf$IFS/parece uma única palavra longa para um correspondente de padrões; o bash expande o Separador de Campo Interno e obtémrm -rf /. - Substituição de comandos.
$(echo rm) -rf /esconde o verbo perigoso dentro de$( ); o guarda que inspeciona a string externa nunca vêrm. - Pipelines codificados.
echo <base64> | base64 -d | sh— cada token visível é inofensivo; a carga só existe após a decodificação. - Flags destrutivas alternativas. Nenhum
rm:find /x -delete,tar -C / -x,sed -i. Uma lista negra construída em torno dermeddnunca dispara.
A Adversa lançou esses truques contra onze dos agentes de código e de uso
de computador open source mais usados — opencode, Goose, Cline, Roo-Code,
Aider, Plandex, Open Interpreter, OpenHands, SWE-agent e o projeto Hermes
entre eles, somando cerca de 548.000 estrelas no
GitHub
entre todos em maio. Dez caíram. O único que resistiu, Continue, resistiu
por um motivo específico: em vez de corresponder à string bruta, ele
tokeniza o comando do jeito que o bash fará antes de decidir — absorvendo
as aspas, resolvendo $IFS, extraindo o comando interno de uma
substituição, sinalizando qualquer pipe que termina em sh. Ele modela o
shell. É a única coisa que funciona na camada do guarda, e é engenharia
real e cuidadosa que os outros dez terão agora de reproduzir, corretamente,
e manter correta a cada caso de borda do bash e a cada lançamento.
O problema é a camada, não a regex
A tentação é ler o GuardFall como "dez equipes escreveram filtros fracos". Isso ignora o que a Adversa está dizendo. Sua frase mais afiada não é sobre nenhum agente em particular:
Um agente que pode rodar comandos de shell arbitrários no host do operador, controlado por uma regex que corresponde à string emitida pelo LLM, não é uma defesa. Ele falha enquanto está totalmente habilitado e corretamente configurado, porque a correspondência de string não consegue modelar o que o bash vai rodar.
Totalmente habilitado e corretamente configurado. Isto não é uma má configuração que você possa fechar. O guarda fica na única camada onde ele nunca pode vencer — entre um modelo que escreve strings e um shell que as reinterpreta — e pede a um correspondente de texto que preveja a saída de um expansor Turing-completo. A abordagem tokeniza-e-canoniza do Continue estreita a lacuna ensinando o guarda a pensar como o bash, e é o movimento certo se você vai manter um guarda ali. Mas é um compromisso por agente e por lançamento de superar a análise de um shell que passou trinta anos acumulando maneiras de reescrever um comando. Nove outros agentes populares mostram como é fácil errar.
Os controles compensatórios da Adversa são reveladores. Antes de qualquer
correção estrutural, eles mandam você redirecionar o $HOME para um
sandbox restrito que mantém o acesso ao projeto mas remove as credenciais,
retirar as flags de execução automática, impedir que agentes rodem em pull
requests não confiáveis, e tratar todo arquivo de configuração de
repositório como código não confiável. Releia essa lista. Não é conselho
sobre escrever um filtro melhor. É conselho sobre construir uma caixa em
torno do agente para que, quando o filtro perder — e eles estão dizendo que
vai perder — o comando que passa aterrisse em algum lugar onde não possa
machucar você.
Essa caixa é o produto.
O Bromure nunca pediu ao guarda para ler o bash
O Bromure Agentic Coding parte da suposição que o GuardFall prova: o
agente vai, mais cedo ou mais tarde, rodar um comando que você não
sancionou. Ele não tenta pegar esse comando lendo-o. Ele roda o agente
inteiro — Aider, Goose, opencode, qual dos dez você preferir — dentro de
uma VM Linux descartável, e roteia cada requisição de rede por um proxy no
host. A pergunta de projeto nunca é "o filtro vai reconhecer este rm?".
É "quando o rm rodar, o que ele alcança?".
Passe as próprias cargas do GuardFall por essa caixa.
O ponto do ataque, uma vez que um r''m oculto ou um find /x -delete
faz um README com armadilha escapar do guarda, é roubar o que a conta pode
alcançar — a Adversa cita ~/.ssh, ~/.aws, credenciais de nuvem,
"qualquer coisa que esteja na sua pasta pessoal" — e apagá-lo ou
exfiltrá-lo. No Bromure, essas são as coisas que nunca estiveram na caixa.
Os segredos reais nunca entram na VM: quando você dá a um perfil uma
AWS_SECRET_ACCESS_KEY, um token do GitHub, uma chave da Anthropic, o
ambiente do agente recebe um substituto brm_…, e o proxy do host troca o
falso pelo valor real no fio, apenas na requisição de saída ao provedor que
deve recebê-lo. A mitigação recomendada pela Adversa — mover o $HOME para
algum lugar que "mantém o acesso ao projeto mas remove as credenciais" — é
uma versão artesanal e parcial do que um perfil Bromure faz por padrão,
para cada credencial, sem você ter de scriptar.
A metade destrutiva aterrissa do mesmo jeito. Um find /x -delete ou um
sed -i que escapa do guarda de fato roda — o Bromure não finge que pegou
o comando. Ele roda contra um diretório pessoal clonado de uma base
compartilhada, numa VM que você pode apagar e resetar para a base a partir
de um menu, não de um formulário de incidente. A persistência que uma carga
possa deixar morre nesse reset. E porque cada requisição sai pelo proxy do
host, o beacon curl … | base64 -d que a classe de pipelines codificados
do GuardFall foi feita para esconder não é invisível: é uma linha
registrada e atribuível no Registro de Segurança.
O único lugar onde o fio vence o shell
O Bromure mantém sim um guarda de operações destrutivas — seus Guardrails do lado do host, sobre os quais escrevemos depois que um agente do Cursor apagou um banco de dados de produção em nove segundos. E aqui a camada joga a favor do Bromure, porque os Guardrails não vivem onde o GuardFall vive.
O GuardFall é um ataque de texto de shell. Cada uma de suas cinco classes
— remoção de aspas, $IFS, $( ), pipelines base64, flags exóticas — é um
truque de como o bash analisa uma string. Os Guardrails do Bromure nunca
leem essa string. Eles ficam no proxy do host e classificam a chamada de
API estruturada que o agente faz a um provedor que ele entende — a
requisição HTTPS real ao AWS, ao Kubernetes, a uma forja git, a um banco de
dados gerenciado — e retornam um 403 firme nas destrutivas, no fio, onde
um agente comprometido na VM não pode desligá-las. Quando uma requisição
chega a essa camada, ela já é um DeleteDBInstance analisado, não uma
string de aspas e cifrões. Não há reescrita de shell para contrabandear
nada, porque não há shell no caminho. A técnica inteira do GuardFall
precisa de um bash entre a verificação e a ação; no caminho dos Guardrails,
não há um.
O que isto delimita, para deixar claro
O comando ainda roda
O Bromure é isolamento, não interceptação. Uma carga GuardFall que escapa do guarda do seu próprio agente vai executar dentro da VM. O que o Bromure muda é o raio de dano: um home descartável, credenciais-isca, um caminho de saída registrado. Se você precisa que o comando em si seja recusado, isso é trabalho do guarda do seu agente — e o GuardFall é o motivo pelo qual você não deveria depender dele.
Destruição local é descartabilidade, não um bloqueio
Um find /x -delete contra arquivos dentro da VM não é uma chamada de
API de provedor, então os Guardrails não o controlam. A resposta à
destruição dentro da VM é que a VM é descartável e o trabalho real vive
num repositório montado e no host, não que o delete foi impedido.
Resetar para a base, não reverter.
A substituição cobre as credenciais que você configura
A troca brm_… protege os segredos que você põe num perfil — chaves de
modelo, tokens de nuvem e git, endpoints de bancos de dados
gerenciados. Uma senha que você cola à mão num arquivo dentro da caixa,
ou um token que um script escreve em disco no meio da sessão, é apenas
um arquivo. Guarde os segredos no broker, não no espaço de trabalho.
A saída é registrada, não proibida por padrão
O beacon de exfiltração aparece no Registro de Segurança; isso é atribuição, não prevenção. Nada real sai porque as credenciais são iscas, mas se você precisa que a VM seja impedida de falar com hosts arbitrários, isso é uma política de rede que você ainda define.
A parte que se generaliza
O GuardFall é um enunciado limpo de uma regra que a categoria inteira não para de reaprender: você não pode tornar um agente seguro pedindo a um filtro que preveja o que seu comando vai fazer. O modelo escreve uma string, e em algum lugar abaixo dele um shell, um cliente de API, um gerenciador de pacotes ou um navegador reinterpreta essa string com suas próprias regras. Toda defesa que inspeciona a saída do agente e torce para que ela corresponda ao comportamento final está apostando contra essa lacuna, e a lacuna sempre vence — venceu aqui em dez dos onze agentes que estavam, nas palavras da Adversa, totalmente habilitados e corretamente configurados.
O Bromure Agentic Coding não faz essa aposta. Ele assume que o comando vai rodar, que o guarda vai às vezes falhar, e que o agente que você convidou pode ser virado contra você por um README que você nunca escreveu. Então ele torna o lugar onde o comando roda não valer a pena atacar: chaves reais no host, iscas na caixa, uma VM descartável, um bloqueio firme reservado ao fio onde nenhum shell pode reescrevê-lo, e um registro de tudo que tentou sair. Você pode rodar qualquer um dos dez agentes que o GuardFall quebrou — o resultado é a mesma caixa descartável de qualquer jeito. É gratuito e open source.