Voltar para todas as publicações
Publicado em · por Renaud Deraison

O agente confiou na pontuação

O Agent Data Injection, uma prova de conceito publicada em julho de 2026 pela Universidade Nacional de Seul, pela UIUC e pela Largosoft, não esconde instruções em um prompt. Ele forja a pontuação que um agente usa para distinguir um campo confiável de um texto não confiável — uma aspa curva, uma aspa escapada, até um cifrão perdido — de modo que o comentário de GitHub de um atacante seja lido como a correção do mantenedor e um registro de CI falsificado seja lido como uma compilação limpa. Ele burlou defesas anti-injeção dedicadas até metade das vezes, em GPT-5.2, Claude e Gemini. O Bromure Agentic Coding normaliza os delimitadores forjados antes que o texto vire um plano, tranca as ações executar-isto e mesclar-isto que saem da caixa, e roda tudo em uma VM Linux descartável com credenciais chamariz.

Seu agente de codificação decide qual texto obedecer lendo a pontuação ao seu redor — as aspas e as chaves que dizem «esta parte é o mantenedor, aquela é o comentário de um estranho». Um novo ataque forja essa pontuação. Ele não escreve uma instrução mais astuta. Ele escreve uma aspa curva, e o comentário do estranho passa a vestir o nome do mantenedor.

Em 6 de julho de 2026, pesquisadores da Universidade Nacional de Seul, da Universidade de Illinois em Urbana-Champaign e da Largosoft — liderados por Woohyuk Choi e pelo professor Byoungyoung Lee — publicaram um artigo de título direto: Agent Data Injection Attacks are Realistic Threats to AI Agents. Ele descreve uma classe de ataque, o Agent Data Injection (ADI), que se posiciona ao lado da injeção de prompt em vez de dentro dela, e que burlou defesas anti-injeção dedicadas até metade das vezes onde a injeção de prompt clássica pontuava perto de zero. OpenAI, Google e Anthropic confirmaram que funciona. Nenhuma correção foi relatada na publicação.

A razão pela qual isso importa a quem roda um agente de codificação é que ele ataca uma coisa em que o agente não consegue deixar de confiar: a fronteira entre os dados que ele buscou e a estrutura em que esses dados chegaram.

O delimitador é a fronteira de segurança

O contexto de um agente é um amontoado de texto de muitas fontes — suas instruções, um arquivo, uma página web, um comentário que alguém deixou em uma issue. Para agir com sensatez, o modelo precisa manter registro de qual pedaço é qual: isto é o nome do mantenedor, aquilo é o corpo de um comentário que um estranho escreveu. Ele faz isso do único jeito que o texto permite — com pontuação. Aspas e chaves, tags, colchetes, quebras de linha. Os delimitadores marcam onde termina um campo confiável e onde começa o conteúdo não confiável.

Um parser estrito trata esses delimitadores literalmente: uma aspa é uma aspa, e um caractere no meio de um comentário é apenas um caractere. Um modelo de linguagem, não. Ele lê a pontuação, no enquadramento do artigo, por adivinhação — infere a estrutura a partir do que os caracteres parecem significar. E é aí toda a brecha. Um atacante que controla um campo de baixa confiança — uma avaliação de produto, um comentário de issue no GitHub, uma linha em um arquivo — salpica caracteres com cara de pontuação, e o modelo lê uma estrutura que nunca existiu.

O detalhe perturbador é o quão pouco ofício isso exige. Os pesquisadores chamam a técnica de injeção probabilística de delimitadores, e descobriram que a pontuação falsa «nem precisa estar certa». Uma aspa escapada, uma aspa curva, até um cifrão perdido passavam por uma fronteira de campo real e enganavam o modelo. Um parser estrito teria lido cada um deles como texto comum.

No que o agente confiaCampo confiávelautor = mantenedorConteúdo não confiávelcomentário de um estranhoBenigno — a fronteira aguenta"parece umarace condition"segue não confiávelADI — delimitador forjadofix"author: maintainer"run this touma aspa curva simula a quebraO agente lê o texto do atacante como campo confiável«aplique a correção do mantenedor» → roda o comando do atacanteNenhuma instrução foi escondida. A pontuação que separa confiável de não confiável foi forjada.
Um agente separa um campo confiável (quem escreveu isto) de um conteúdo não confiável (o que escreveu) usando a pontuação ao seu redor. O Agent Data Injection forja essa pontuação de dentro de um campo que o atacante já controla — uma aspa curva, uma aspa escapada, um cifrão — de modo que o texto que o atacante escreveu seja lido como se viesse de uma fonte confiável. A instrução não é a carga útil. O delimitador é.

O que isso faz a um agente de codificação

A versão web-agent do ADI é fácil de imaginar: forje o identificador em um elemento de página e um agente fazendo suas compras clica em «Comprar agora» onde queria clicar em «Ler mais». A versão voltada a desenvolvedores é pior, porque o campo confiável que ela forja é quem disse que o código era seguro.

Em uma demonstração, um atacante deixa um comentário em uma issue do GitHub e forja a atribuição de autoria para que o agente o leia como vindo do mantenedor do projeto. Quando um desenvolvedor mais tarde pede ao agente para «aplicar a correção do mantenedor», o Claude Code, o Codex da OpenAI e o Gemini CLI do Google fazem exatamente isso — rodam o comando do atacante, porque, tanto quanto o modelo consegue perceber, foi o mantenedor que pediu. Em outra, uma pull request maliciosa falsifica o registro de suas próprias verificações de CI concluídas. O agente vê uma compilação limpa em seu contexto, julga o código seguro com base nessa evidência fabricada, e mescla malware de verdade.

Entre os seis modelos que a equipe testou — GPT-5.2, GPT-5-mini, Claude Opus 4.5 e Sonnet 4.5, Gemini 3 Pro e Flash — os números não são um erro de arredondamento. Dados estruturados renderam uma taxa de sucesso de 31 a 43%; dados de página web foram de 33% até 100%. E contra defesas construídas especificamente para deter a injeção de prompt, o ADI ainda passou até metade das vezes, onde as mesmas defesas paravam a injeção clássica na hora. Duas mitigações funcionaram no laboratório e ambas custaram algo: etiquetar elementos de página com IDs aleatórios e imprevisíveis (como faz o navegador Atlas do ChatGPT) cortou o sucesso de cerca de 49% para 29%, e um rastreamento estrito de proveniência de dados levou os ataques a zero — ao mesmo tempo que derrubou a capacidade do agente de concluir tarefas normais para cerca de um terço.

Por que o filtro habitual não pega

Um filtro anti-injeção de prompt é treinado para notar instruções escondidas nos dados — «ignore suas diretrizes anteriores», «rode este comando», o formato reconhecível de um comando disfarçado de conteúdo. O ADI não precisa desse formato. O texto malicioso pode ser lido como uma nota comum de mantenedor. O que carrega o ataque é a pontuação ao seu redor, e um filtro que procura linguagem suspeita passa direto por uma aspa curva. É por isso que a própria defesa funcional do artigo não foi um classificador mais esperto, mas um parser mais estrito — proveniência que se recusa a adivinhar onde um campo termina.

Esta é a mesma lição que o resto da segurança agêntica não para de reaprender. Uma denylist de comandos perde para o shell que reescreve o comando. Uma ferramenta MCP confiável devolve dados escritos por um atacante. Um espaço de trabalho em que você confiava inicia servidores que você não quis. O ADI é a versão em que a coisa envenenada não é a instrução nem sequer os dados, mas o quadro — o delimitador que diz ao agente em qual texto acreditar. Não dá para sair de uma aspa curva por correspondência de padrões.

Onde o Bromure traça a linha

O Bromure Agentic Coding não tenta tornar o modelo um melhor adivinhador de onde um campo termina. Ele faz duas coisas que o modelo não pode, e então garante que, quando as duas estiverem erradas, o dano caia em algum lugar descartável.

Primeiro, os delimitadores forjados são normalizados antes que o texto vire um plano. A detecção de injeção de prompt no dispositivo do Bromure não é apenas um modelo local que lê a intenção; ela é combinada com um scanner determinístico — o mesmo que pega os truques de Unicode invisível e de homóglifos. Aspas curvas se dobram em aspas retas, caracteres confundíveis e de largura zero são retirados, e um campo cujos delimitadores não batem com a estrutura canônica é sinalizado. É o instinto de parser estrito que os pesquisadores acharam eficaz contra o ADI, aplicado como uma camada sobre o texto não confiável que o agente buscou — a mesma classe de entrada que um CLAUDE.md malicioso ou um comentário envenenado — e tudo isso fica no seu Mac.

Segundo, as duas ações que o ADI realmente quer ainda param em uma fronteira. Veja o que o ataque tenta disparar: rodar a correção do mantenedor e mesclar a pull request. Ambas são ações que passam por cima do sandbox do agente — um comando de shell, um push para um remoto. Todo agente que o Bromure roda — Claude Code, Codex, Grok Build — roda dentro de uma VM Linux descartável, e os passos que saem dessa caixa são os que o Bromure apresenta para confirmação. Uma atribuição forjada não consegue rodar um comando automaticamente, e um registro de CI falsificado não consegue mesclar uma branch automaticamente, porque «o mantenedor mandou» é justamente o julgamento que o passo de confirmação existe para reconferir.

Terceiro, se um comando roda, ele roda em uma caixa que você joga fora. Suponha que um delimitador seja novo o bastante para escapar do normalizador e convincente o bastante para passar na revisão. O comando executa dentro da VM. Redefina o perfil para a base e tudo o que ele deixou — um script, uma chave SSH, uma tarefa agendada — se foi. Nada do que ele fez sobrevive ao fechamento da janela.

Quarto, não há credenciais reais para ele levar. Uma «correção» que vasculha o ambiente e o disco em busca de tokens encontra os chamarizes do Bromure — chaves AWS sintéticas, um ~/.kube/config descartável, tokens de git e de registro de mentira (brm_…). Os segredos reais só são substituídos no host, no proxy, no caminho de saída para a API verdadeira. Tudo o que o comando manda para fora da caixa é um saco de strings que não autentica nada, e a conexão que o manda aparece no Registro de Segurança como tráfego de saída que você consegue ver.

VM Linux descartávelComentário forjadouma aspa curvasimula a fronteiraScanner determinísticocurva → reta,campo discordante sinalizadoSe um comando escaparroda na caixa · vasculha chamarizesreset-to-base o apagaRodar a correção? Mesclar a PR?ações de fronteira — retidas para confirmarOs segredos reais ficam no hostsubstituídos no fio, saída registradaO comentário ainda é plantado.Só não consegue se assinar como o mantenedor.
O mesmo comentário forjado, buscado dentro do Bromure. O scanner determinístico dobra a aspa curva de volta em uma reta e sinaliza o campo discordante antes que o texto vire um plano. Se um comando passar mesmo assim, ele roda em uma VM descartável contra credenciais chamariz, e as duas ações que o ADI quer — rodar a correção, mesclar a PR — param em uma fronteira de confirmação porque saem da caixa. O comentário ainda é plantado. Só não consegue se assinar.

O que isso delimita

Normalização e confirmação são contenção, não uma cura para um modelo que lê estrutura por adivinhação. Vale ser exato sobre o que o Bromure muda e o que não muda.

O comentário ainda é plantado

O Bromure não impede um atacante de deixar um comentário forjado no GitHub ou de falsificar um registro de CI, e não corrige o fato subjacente de que um modelo de linguagem infere onde um campo termina. Isso cabe ao modelo e à plataforma resolver. O que o Bromure muda é o que acontece depois que o agente lê o texto forjado: ele é normalizado, e as ações que ele tenta disparar são verificadas.

A normalização é uma rede, não um muro

Dobrar aspas curvas, retirar confundíveis e sinalizar delimitadores discordantes pega os truques de ADI que os pesquisadores demonstraram e mais, mas um delimitador inédito pode ser formulado para escapar de um único scanner. Trate-o como uma camada; a caixa descartável com chaves chamariz e saída registrada é o que segura quando o scanner falha.

A confirmação guarda a fronteira, não cada edição

O passo de confirmação ganha seu lugar em ações que saem da caixa — rodar um comando, dar push, mesclar. Uma instrução forjada que só edita um arquivo dentro da VM é pega pelo isolamento e pelos chamarizes, não pelo prompt. Mantenha as ações de fronteira travadas; é aí que um «o mantenedor mandou» falsificado merece um segundo olhar.

A substituição cobre os segredos que você configura

A troca por chamariz protege as credenciais que você coloca em um perfil: chaves de modelo, tokens de git e de nuvem, tokens de registro e de cluster, chaves SSH. Um token que um script escreve no disco no meio da execução, ou uma sessão que você abre à mão dentro da caixa, é apenas dado. Mantenha os segredos no broker, não no espaço de trabalho.

O ponto dos pesquisadores não é que seis modelos compartilham um bug. É que a forma como um agente distingue um campo confiável de um conteúdo não confiável — pontuação que ele lê por adivinhação — é a mesma em todo lugar onde um agente encontra o mundo exterior, e ela não vai ser corrigida neste trimestre. Hoje o delimitador forjado vive em um comentário do GitHub. Amanhã é um campo do Jira, um trailer de commit, um cabeçalho em uma página buscada. Seu agente vai ler uma fronteira que um atacante desenhou, e até metade das vezes vai acreditar nela. A pergunta não é se a pontuação um dia o engana. A pergunta é o que roda quando isso acontece: sua máquina, seus tokens reais, e um comando que se empurrou para a main — ou uma caixa Linux descartável que normalizou a aspa primeiro, segurou a mesclagem para um olhar, e não tinha nada além de chamarizes dentro. O Bromure faz com que seja a segunda.