O repo rodou código antes de você digitar uma palavra: GitSpawn e como o Hermes corrigiu isso


Sexta à tarde, um colega compacta um projeto e te manda uma mensagem: “dá uma olhada nesse bug.” Você descompacta o arquivo, arrasta a pasta para dentro do Hermes e começa a digitar sua primeira instrução — mas nesses poucos segundos, um código que não é seu já terminou de rodar na sua máquina, com as suas permissões. Sem popup, sem prompt de aprovação, nada na tela. Isso não é roteiro de filme: é uma classe de vulnerabilidades bem real, divulgada em 1º de setembro pela empresa de segurança Manifold Security sob o nome GitSpawn, que afeta quase todas as ferramentas de codificação com IA do mercado — Claude Code, Codex, Cursor, Goose, Qwen Code, Grok Build e Hermes Agent. A boa notícia: o Hermes mesclou sua correção em 2 de setembro (PR #101483, atualmente na main).

Como funciona: o repo que você abriu “roda” um comando por você

Ferramentas de codificação com IA — incluindo o Hermes — rodam alguns comandos git na inicialização para se localizar: em qual branch você está, quais arquivos mudaram. Essa coleta de contexto acontece automaticamente, antes de qualquer prompt, antes de qualquer chamada de ferramenta, antes de qualquer confirmação de confiança do workspace. O agente precisa saber onde está antes de poder fazer qualquer coisa.

O problema mora num recurso de performance do git: o core.fsmonitor. Em repos grandes, o git não quer escanear cada arquivo para decidir o que mudou, então ele permite configurar um programa auxiliar para responder essa pergunta no lugar dele. O git roda esse programa a cada index refresh — e comandos como git status e git diff disparam um index refresh.

O detalhe: o git lê essa configuração do .git/config do próprio repo. Então um repo hostil pode embarcar isto:

[core]
    fsmonitor = /tmp/pwn.sh

Aí tudo o que você precisa fazer é abrir o repo — sem dizer uma palavra — e o git status que o Hermes roda automaticamente faz o git executar /tmp/pwn.sh. Como você, com os seus privilégios, fora do sandbox, sem nenhuma interface de aprovação. Um atacante ganha mais do que “capacidade de rodar código”: ele leva suas chaves SSH, credenciais de cloud, tokens de shell e um ponto de apoio na máquina inteira.

O core.fsmonitor é apenas um dos pontos de execução da classe. O relatório da Manifold também cobre core.hooksPath (hooks no checkout), configurações de pager/editor/credentials e os diff drivers mais sorrateiros, escopados via .gitattributes ([diff \"x\"] command= / textconv=, executados quando um diff é renderizado). Esse último tipo é o pior: o atacante escolhe o nome do driver, então sobrescritas por variáveis de ambiente não conseguem enumerá-lo — só flags de linha de comando conseguem desligá-lo.

Como se espalha: por que git clone é seguro e arquivos zip não são

Essa vulnerabilidade tem uma propriedade contraintuitiva: clonar um repo hostil pela rede é seguro. O clone/fetch/pull do git nunca transfere o .git/config — ele é um arquivo privado do seu repo local, e a versão do remoto é irrelevante para você.

O que é perigoso é um repo que chega como arquivos de diretório: com a pasta .git intacta. Um zip compartilhado, uma pasta de cloud sincronizada, um pendrive, um diretório de projeto que um colega copiou direto — todos preservam o .git/config de quem enviou. As provas de conceito da Manifold usaram um zip.

Então a regra prática é simples: desconfie de “pastas de projeto empacotadas” que outra pessoa te entregou antes de abri-las com uma ferramenta de IA; qualquer coisa que você obtiver com git clone é inerentemente segura.

Resposta da indústria: oito achados, quatro ainda sem correção na divulgação

A Manifold Security publicou o relatório completo em 1º de setembro, cobrindo oito achados em sete ferramentas de codificação com IA. Status na publicação:

Ferramenta Status
Claude Code (caminho fsmonitor) Corrigido (2.1.196)
Claude Code (caminho ultrareview) Sem correção na divulgação (ainda vulnerável na 2.1.252)
Goose Corrigido (1.44.0, CVE-2026-72718)
Codex / Cursor Corrigido
Hermes Agent Sem correção na divulgação — correção mesclada em 2 de setembro
Qwen Code / Grok Build Sem correção na divulgação

A cobertura do The Hacker News de 2 de setembro ainda listava o Hermes como “correção pendente” — mas a Nous Research mesclou a correção na main no mesmo dia, um dia mais fresca do que a reportagem.

A correção do Hermes: transformando o “git puro” em “git sanitizado”

A correção (PR #101483, commit f6234d00c5) é direta no conceito: toda sonda git que o próprio Hermes inicia agora roda em um ambiente sanitizado que ignora completamente a configuração do próprio repo.

Duas camadas de defesa:

Camada 1 — sanitização do ambiente (noninteractive_git_env()). Todas as sondas automáticas agora usam por padrão um “ambiente git não interativo” que fixa core.fsmonitor, core.hooksPath, pager, editor e credential helpers em valores inertes via GIT_CONFIG_*, e ignora a config global e a do sistema. Quando o git status faz o refresh do index, não existe mais nenhum “programa auxiliar especificado pelo repo” para rodar. Os pontos de chamada cobertos incluem o snapshot de contexto do workspace (coding_context), a construção da project-tree no gateway, as referências de contexto @diff/@staged, o fingerprint do goal-gate e o -w de worktree add na inicialização.

Camada 2 — flags de linha de comando (harden_git_argv()). Variáveis de ambiente não alcançam os drivers escopados por .gitattributes (o atacante nomeia o driver, então você não consegue enumerá-lo), então, para os subcomandos que renderizam diffdiff, show, log, blame — o Hermes agora injeta --no-ext-diff --no-textconv, cortando os dois pontos de execução ([diff \"x\"] command= e textconv=) no nível da linha de comando.

Um suite de regressão end-to-end com git real acompanha a correção: ele arma um repo com config maliciosa e verifica que todo caminho automático falha ao executar fsmonitor, hooks, external-diff ou textconv.

O que você deve fazer agora

  1. Saiba sua versão: a correção chegou em 2 de setembro e ainda não está em nenhum release formal (o release mais recente, v0.21.0, saiu em 31 de agosto — antes da correção). Se você quer proteção desde o primeiro dia, acompanhe a main ou espere o próximo patch release; de qualquer forma, comece a praticar os hábitos abaixo.
  2. Desconfie de repos “em formato de arquivo”: confira zips, pastas sincronizadas e diretórios de projeto copiados via pendrive antes de abri-los. Repos que você obtém com git clone não exigem essa preocupação.
  3. Confira você mesmo um projeto recebido antes de entregá-lo ao Hermes:
cd path/to/suspicious-project
git config --get core.fsmonitor      # output here = be alert
git config --get core.hooksPath
grep -nE "command *=|textconv *=" .git/config
  1. Não abra uma sessão direto num diretório suspeito: se você precisar revisar o código, faça git clone de uma cópia limpa primeiro e aponte o Hermes para ela.

Esse incidente se junta ao portão de aprovação de config SSH que cobrimos antes como a mesma classe de lição: os comandos de baixo nível que uma ferramenta de IA roda automaticamente precisam assumir que sua entrada não é confiável. A correção do Hermes puxa até o passo mais inicial e invisível — a coleta de contexto — para dentro do trust boundary. Onde você não consegue ver, ela agora assume que o repo pode ser o inimigo.