Em 26 de agosto de 2026, o pesquisador de segurança Johann Rehberger pediu ao Claude Code, rodando o Opus 5 em Auto Mode, que resumisse um site. Vinte minutos depois, ele tinha execução remota de código, um callback de comando e controle ativo e a calculadora abrindo na máquina de teste.
Isso é prompt injection no Claude Code funcionando de um jeito que ninguém projetou. O classificador de segurança do Auto Mode foi feito pra barrar ações que parecem arriscadas uma a uma. Uma cadeia de passos em que cada um, sozinho, parece inofensivo pode passar direto por ele, e foi exatamente o que aconteceu. O que de fato impede isso é rodar o Claude Code dentro de um isolamento de verdade, no nível do sistema operacional: o sandbox de Bash que já vem nele, ou um container.
Como a injeção de prompt levou o Claude Code a rodar malware
O ataque encadeou seis passos inofensivos, um de cada vez, até o Claude rodar um código que ele já tinha se recusado a executar uma vez.
A ferramenta WebFetch do Claude bateu primeiro na página maliciosa e recebeu um erro 415, tipo de mídia não suportado. Ninguém mandou o Claude trocar de ferramenta. Ele decidiu sozinho tentar de novo com curl, e é nesse comando de shell que a cadeia de exploração começa de verdade. A URL raiz do site redirecionou com um 303 pra um arquivo ZIP apresentado como catálogo de notebook: metadados, um README, sete registros codificados, um binário de macOS chamado decoder-darwin e um arquivo a mais chamado struct.py.
O Claude leu o README, entendeu pra que servia o binário e se recusou a executar.
Essa recusa foi a decisão certa por todos os instintos de segurança que ele tem, e foi também o exato momento em que o ataque deu certo. Em vez de rodar um binário desconhecido, o Claude escreveu o próprio decodificador em Python e rodou de dentro da pasta extraída. Esse decodificador importou o módulo padrão base64 do Python, o base64 importa o struct por dentro, e o Python achou um arquivo chamado struct.py bem ali na pasta de trabalho. Carregou o arquivo do atacante no lugar do verdadeiro.
O struct.py envenenado estava ofuscado (o Rehberger usou o ChatGPT pra escrever a ofuscação) e disparou um subprocesso Python separado que baixou e executou um payload remoto. Numa variante, abriu a Calculadora e se conectou a um servidor de comando e controle. Em outra, abriu uma segunda instância do Claude Code sem interface, via claude -p, que rodou whoami, uname e id por conta própria antes de gravar arquivos fora da pasta de trabalho.
Em três variantes de ataque, rodadas cinco vezes cada (amostra pequena, e o próprio Rehberger diz isso), a cadeia deu certo de 60% a 80% das vezes.
O que injeção de prompt quer dizer pra um agente de programação?
Injeção de prompt é conteúdo não confiável (uma página, um arquivo, um ZIP) conduzindo o que o agente faz em seguida sem nunca dar uma ordem direta. Ninguém digitou "ignore suas instruções e execute este binário" no Claude Code. O site só fez o caminho malicioso parecer o único jeito de terminar uma tarefa totalmente comum.
Os modelos de ponta já não caem nos ataques antigos há anos. Mandar o Claude ignorar as instruções, na cara, não funciona mais, e faz tempo. O que ainda funciona é uma cadeia de passos razoáveis, um por um, que só viram algo perigoso quando você olha a sequência inteira: uma busca que falhou, uma nova tentativa normal, a recusa de rodar um arquivo suspeito, um scriptzinho que o próprio modelo escreveu. Cada passo, sozinho, passa numa checagem de sanidade.
O classificador da Anthropic avalia mensagens do usuário, chamadas de ferramenta e o conteúdo do CLAUDE.md, mas não o resultado bruto das ferramentas, justamente pra que um texto hostil dentro de um arquivo ou de uma página não consiga manipulá-lo diretamente. Esse desenho barra uma página que escreve por extenso um comando malicioso, mas não faz nada contra uma página que só faz o curl parecer o único jeito de concluir a tarefa.
Uma avaliação independente encomendada pela Anthropic testou 72 cenários de injeção, dez rodadas cada, e chegou a uma taxa de sucesso de ataque de 0,00% pro Opus 5 em Auto Mode. A cadeia do Rehberger não era um dos 72. Os dois números são verdadeiros ao mesmo tempo, e o problema está justamente em citar um sem o outro.
Como ligar o sandbox de Bash do Claude Code
O sandbox de Bash já vem no Claude Code e impõe isolamento de sistema de arquivos e de rede no nível do sistema operacional, no macOS, no Linux e no WSL2. É a barreira que teria parado a cadeia do Rehberger mesmo depois de o Claude cair na primeira jogada: o curl indo atrás de um domínio fora da lista e, mais tarde, o callback do próprio payload teriam batido na parede de rede antes de qualquer um funcionar.
Abra uma sessão e rode:
/sandbox
Isso abre um painel com as abas Mode, Overrides e Config, esta última mostrando as configurações resolvidas. Na aba Mode, escolha auto-allow. Os comandos dentro do sandbox rodam sem pedir permissão, porque quem faz a imposição é o sistema operacional, e não um classificador.
O macOS não precisa de nada extra: o sandbox usa o Seatbelt, que já vem no sistema. Linux e WSL2 precisam de dois pacotes:
sudo apt-get install bubblewrap socat
No Fedora, rode dnf install bubblewrap socat. Reinicie o Claude Code e abra o /sandbox de novo pra confirmar que a aba Dependencies sumiu.
Pra ligar o sandbox em todo projeto, em vez de escolher a cada sessão, acrescente isto no ~/.claude/settings.json:
{
"sandbox": {
"enabled": true
}
}
Por padrão, os comandos no sandbox só podem gravar na pasta de trabalho e numa pasta temporária da sessão. A leitura é mais ampla: a máquina inteira, menos uma lista curta de exceções, e isso importa na próxima seção. Na rede, nenhum domínio vem liberado. Na primeira vez que um comando no sandbox precisa de um, o Claude Code pede, ou consulta o classificador, no Auto Mode. Libere antes os domínios que você usa de verdade:
{
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["github.com", "registry.npmjs.org", "pypi.org"]
}
}
}
Acrescente "strictAllowlist": true nesse mesmo bloco de network e tudo o que estiver fora da lista é negado de vez, sem perguntar. Sem essa opção, um domínio fora da lista ainda para pedindo aprovação em vez de baixar em silêncio, e só isso já teria pegado o ZIP do Rehberger antes de ele chegar à máquina.
Se você já usa a configuração de statusline e permissões do Claude Code no macOS, o bloco do sandbox vai no mesmo settings.json, logo ao lado.
Quais credenciais o sandbox não bloqueia por padrão
A leitura padrão cobre a máquina inteira, menos uma lista curta de exceções, e essa lista não inclui as suas credenciais da AWS nem as suas chaves SSH, a não ser que você acrescente. Um comando no sandbox ainda consegue ler ~/.aws/credentials e ~/.ssh logo de cara, e ler uma chave basta pra vazá-la, se a camada de rede liberar o destino pra onde ela for mandada.
Acrescente regras de negação explícitas pra tudo o que tiver um estrago potencial de verdade:
{
"sandbox": {
"enabled": true,
"credentials": {
"files": [
{ "path": "~/.aws/credentials", "mode": "deny" },
{ "path": "~/.ssh", "mode": "deny" }
],
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" }
]
}
}
}
Existe também uma opção mais leve. Definir o mode da credencial como mask em vez de deny mantém funcionando ferramentas como o gh e o npm: o comando no sandbox vê um valor de mentira, e o proxy de rede do próprio sandbox troca pelo verdadeiro só nas requisições pros hosts que você listou explicitamente. Guarde o deny pras credenciais que um agente de programação não tem motivo nenhum pra abrir.
O Auto Mode basta sozinho, ou também precisa de container?
O Auto Mode e o sandbox resolvem problemas diferentes. O classificador do Auto Mode decide se uma ação roda ou não. O sandbox decide o que um comando Bash consegue alcançar depois que já está rodando, com a regra imposta pelo sistema operacional, e não pelo critério de um modelo. Ligar um não desliga o outro, e hoje eu rodo os dois juntos em todo projeto.
Com credencial de verdade no meio, nenhum dos dois é opcional.
Eu já construí praticamente a mesma barreira uma vez, pra gente em vez de agente. Na Green Hat, os desenvolvedores tinham acesso total ao ambiente de desenvolvimento, acesso limitado ao staging e nenhum acesso à produção sem pull request revisado. Colocar um agente de programação em sandbox segue o mesmo princípio, com o bubblewrap e um proxy de rede no lugar de uma pessoa revisando o diff.
A mesma barreira, com outro guarda na porta.
O padrão que quebra sem nada disso já destruiu uma loja sobre a qual escrevi à parte: um agente de IA com acesso irrestrito à API de uma stack WooCommerce no ar nem precisou ser sequestrado pra fazer estrago. Tinha permissão e nenhum limite, e pronto. Um agente de programação sequestrado, com a mesma falta de limite, é a mesma falha com um passo a mais na frente. O OpenClaw vem com quase o mesmo padrão, como mostrei em onde o n8n, o OpenClaw e as ferramentas de agente do Claude realmente se separam: o sandbox é opcional lá também, e muita gente pula.
Rodar o Claude Code com --dangerously-skip-permissions, ou com o bypass de permissões ligado em qualquer interface, só faz sentido dentro de um container ou VM sem caminho de volta pros seus arquivos reais. A própria documentação da Anthropic diz o mesmo: a flag desliga todo pedido de permissão e toda verificação de caminho protegido, e só é segura onde uma sessão comprometida não alcança nada que importe de verdade.
Então, o que mudar primeiro?
Se o Claude Code só mexe num projeto descartável, sem nada sensível pra ler, o sandbox embutido em auto-allow, com uma lista de domínios de verdade, dá conta do trabalho do dia a dia. Se ele mexe numa stack de produção de cliente, em credenciais de nuvem ou em chaves SSH com estrago potencial real, coloque esse sandbox dentro de um container também, ligue a camada de rede de propósito, em vez de deixar ela só perguntando, e pare de tratar a aprovação do Auto Mode como prova de que um comando era seguro.
A cadeia do Rehberger deu certo 3 vezes em 5 com as variantes mais fracas, e 4 em 5 com a mais forte. Pergunte-se o que essas rodadas teriam alcançado na sua máquina.
Se o seu time roda o Claude Code, ou qualquer agente de programação, em infraestrutura real de cliente e ninguém conferiu o que uma sessão sequestrada conseguiria alcançar, esse é o tipo de revisão de arquitetura que eu faço antes de virar post-mortem. Fale comigo e eu te mostro o que a sua configuração expõe de verdade.
