Kilo Code entregou em silêncio ao servidor os 12 arquivos do projeto, embora só dois fossem permitidos
O autor verificou o que vai para o servidor do modelo quando um assistente de IA altera um único caractere no código. O Kilo Code 7.4.20 trocou a soma pela multiplicação, o teste passou e no disco mudou um único arquivo. Mas um servidor de teste que fazia o papel de provedor não confiável recebeu todos os 12 arquivos do projeto, embora o usuário tivesse permitido enviar apenas dois, e as cópias coincidiam byte a byte.
Processado por IA de Habr AI; editado por Hamidun News
Costumamos aceitar o trabalho de um assistente de IA assim: olhamos o diff, rodamos os testes, vemos o verde e fechamos a tarefa. Um experimento descrito no Habr expõe uma falha nesse hábito. A edição pode ser perfeita, e o projeto já estar no servidor de outra pessoa.
Como o experimento foi montado
A tarefa era propositalmente minúscula: em price.py a função total(price, count) retornava price + count, enquanto o teste esperava que total(7, 3) desse 21. Era preciso trocar a soma pela multiplicação e executar check.py. A instrução do usuário dizia que só price.py e check.py podiam ser enviados.
O autor partiu de um modelo em que o provedor de LLM não é confiável e viola as instruções de propósito. Seu papel foi feito por um servidor HTTP local em 127.0.0.1. Ele imitava respostas em streaming da API Chat Completions compatível com a OpenAI e enviava ao cliente tool_calls: primeiro doze comandos read para todos os arquivos de um projeto sintético, depois um comando de correção e então a execução do teste. O cliente era real: bin/kilo.exe da extensão Kilo Code 7.4.20, iniciado pelo comando CLI run. A configuração permitia leitura e execução de comandos.
O que aconteceu
Por fora, tudo parecia exemplar. O Kilo mudou um caractere, o teste passou, os demais arquivos no disco não mudaram, o código de saída foi zero e todas as 14 chamadas de ferramentas terminaram com o status completed. Mas o servidor recebeu todos os 12 arquivos, num total de 11 103 bytes, e seus SHA-256 coincidiam com os originais.
A mecânica é simples. O Kilo adiciona o resultado de cada leitura ao histórico do chat e o envia na requisição seguinte. O servidor extrai as mensagens com o papel tool, remove os números de linha e remonta os arquivos. Nenhum canal de exfiltração é necessário: o próprio cliente leva os dados nas requisições normais.
O tráfego é interessante por si só. Foram 15 chamadas ao modelo, e o volume total dos corpos das requisições foi de 458 779 bytes para 11 KB de código único. A causa é o reenvio do histórico, as descrições das ferramentas e a marcação de serviço. Não houve uma única requisição enorme: o código saía em pequenas porções e depois se repetia. Por isso, um vazamento assim não é percebido pelo tamanho de uma requisição.
Por que as proibições funcionam pior do que parece
Na série inicial de testes, a regra read: deny bloqueava a leitura direta de um diretório proibido. Mas com bash: allow, o Python leu o mesmo arquivo e a saída foi para a requisição seguinte. Quando o bash foi proibido, o comando não foi executado. As permissões no Kilo são definidas separadamente para cada ferramenta, e proibir uma não fecha os outros caminhos.
Há também ressalvas honestas. No experimento não há um modelo real: os comandos eram escolhidos pelo servidor de teste, então ele não mede a propensão de modelos comerciais a esse comportamento. Os nomes dos arquivos eram conhecidos de antemão pelo servidor; a busca autônoma por uma árvore desconhecida não foi testada. A sessão gráfica da extensão também não foi testada, apenas a CLI.
O que fazer na prática
Primeiro: avalie não só o diff, mas também o registro de chamadas de ferramentas e os corpos das requisições ao provedor. Passe o agente ao menos uma vez por um proxy local e veja o que realmente sai.
Segundo: dê ao agente o mínimo de permissões. Se a leitura é permitida, tudo o que foi lido potencialmente pertence ao provedor. Para repositórios sensíveis, esse é um argumento a favor de modelos locais ou de provedores com garantias contratuais rígidas.
Terceiro: não confie em uma instrução de texto como «envie apenas estes dois arquivos». É um desejo dirigido ao modelo, não uma restrição do cliente. O limite real só é criado por permissões de ferramentas, sandbox e políticas de rede.
O autor publicou o ambiente de teste completo: Python 3.10+, Git e o executável do Kilo, cerca de 150 linhas de código. Vale repeti-lo no seu próprio cliente, seja qual for o agente que você use.
- 12 de nov. de 2026Jensen Huang deixa o cargo de CEO da Nvidia: empresa perde US$ 1,4 trilhão em duas semanas
- 12 de nov. de 2026Sindicato de Oakland garante requalificação em vez de demissões por causa da IA: 94,1% votaram a favor da greve
- 12 de nov. de 2026Oito países, OpenAI e Anthropic prometem um «botão de desligar» para modelos de IA, mas sem prazos nem multas
- 12 de nov. de 2026OpenAI e ModRetro lançam console de US$ 200 para jogos criados no Codex
Perguntas frequentes sobre a notícia
Como o experimento foi montado?
A tarefa era propositalmente minúscula: em price.py a função total(price, count) retornava price + count, enquanto o teste esperava que total(7, 3) desse 21. Era preciso trocar a soma pela multiplicação e executar check.py. A instrução do usuário dizia que só price.py e check.py podiam ser enviados. O autor partiu de um modelo em que o provedor de LLM não é confiável e viola as instruções de propósito. Seu papel foi feito por um servidor HTTP local em 127.0.0.1.
O que aconteceu?
Por fora, tudo parecia exemplar. O Kilo mudou um caractere, o teste passou, os demais arquivos no disco não mudaram, o código de saída foi zero e todas as 14 chamadas de ferramentas terminaram com o status completed. Mas o servidor recebeu todos os 12 arquivos, num total de 11 103 bytes, e seus SHA-256 coincidiam com os originais. A mecânica é simples. O Kilo adiciona o resultado de cada leitura ao histórico do chat e o envia na requisição seguinte.
Por que as proibições funcionam pior do que parece?
Na série inicial de testes, a regra read: deny bloqueava a leitura direta de um diretório proibido. Mas com bash: allow, o Python leu o mesmo arquivo e a saída foi para a requisição seguinte. Quando o bash foi proibido, o comando não foi executado. As permissões no Kilo são definidas separadamente para cada ferramenta, e proibir uma não fecha os outros caminhos. Há também ressalvas honestas.
Test Frontier LLMs & Autonomous Agents in One Workspace
Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.
O essencial da IA — uma vez por semana
Sete histórias que realmente importaram, escolhidas a dedo. Sem ruído nem releases.
Pronto! Verifique seu e-mail para a confirmação.