
Laboratório de reprodução para CVE-2026-54316 (bypass de permissão de hostname simples no WebFetch do Claude Code para huggingface.co / exfiltração)
Um laboratório autocontido e descartável que reproduz
GHSA-fg94-h982-f3mm
/ CVE-2026-54316: o Claude Code pré-aprovou huggingface.co como um hostname simples
para a ferramenta WebFetch, de modo que qualquer caminho nesse domínio — incluindo
repositórios de modelos controlados por atacantes — era buscado sem solicitação de
permissão. Combinado com injeção de prompt, isso se torna um canal fora de banda
para exfiltrar dados, observado por meio das contagens de download no servidor do HuggingFace.
| Aviso | GHSA-fg94-h982-f3mm |
| CVE | CVE-2026-54316 |
| Pacote | @anthropic-ai/claude-code (npm) |
| Afetado | >= 0.2.54, < 2.1.163 |
| Corrigido | 2.1.163 |
| Causa raiz | Lista de permissões por hostname simples em um host multi-tenant (CWE-183) |
Este laboratório reproduz uma vulnerabilidade corrigida e divulgada publicamente para fins educacionais e defensivos. Use-o apenas contra infraestrutura que você possui:
fixtures/canary.env) — nunca use um real.huggingface.co sem solicitação de aprovação, enquanto qualquer outro domínio
gera uma — porque huggingface.co está em uma lista de permissões fixa (hardcoded).O contêiner é o único lugar onde a versão vulnerável é executada; seu host permanece limpo. Autentique-se com um token de assinatura do Claude (nenhuma chave de API é necessária):
docker build -t cve-2026-54316-lab .
docker run --rm -it cve-2026-54316-lab
Dentro do contêiner, execute claude e selecione "Claude account with subscription"
para fazer login interativamente. A versão vulnerável 2.1.162 é anterior à
variável de ambiente CLAUDE_CODE_OAUTH_TOKEN, portanto um setup-token não é usado aqui — o
fluxo interativo de navegador/colagem de código evita totalmente a criação de um token de longa duração.
O ponto central é a assimetria da solicitação de aprovação por domínio; por isso, o WebFetch
permanece disponível (não é negado) — a aprovação é tratada por meio de prompts, o comportamento
padrão. Dentro do contêiner, no claude:
Use o WebFetch para buscar
https://example.come resumi-lo.
→ Uma solicitação de permissão aparece pedindo que você aprove example.com. Depois:
Use o WebFetch para buscar
https://huggingface.co/<your-account>/canary-lab/resolve/main/config.json.
Vulnerável: a busca em huggingface.co prossegue sem prompt, enquanto
example.com exigiu um. Essa assimetria é o bug — huggingface.co está em uma
lista de permissões fixa (hardcoded). (O repositório do HF não precisa existir para este
teste; um 401/404 ainda prova que o prompt nunca foi acionado.) Reconstrua com
@anthropic-ai/[email protected] e a busca em huggingface.co agora também gera prompt —
esse antes/depois é o destaque.
./scripts/make_hf_canary_files.sh ./hf-repo e depois envie hf-repo/ para um
repositório público do HuggingFace que você possui (<your-account>/canary-lab).payloads/untrusted-readme.md, defina HF_ACCOUNT e coloque-o onde o
agente o lerá como entrada não confiável.Dockerfile — versão vulnerável fixada 2.1.162.claude/settings.json — allow/deny vazios para que o WebFetch solicite prompt por domíniofixtures/canary.env — canário fictícioscripts/make_hf_canary_files.sh — estrutura de arquivos canário do HFpayloads/untrusted-readme.md — payload de injeção de prompt (sanitizado)