
Laboratorio di riproduzione per CVE-2026-54316 (bypass dei permessi tramite bare-hostname / esfiltrazione di Claude Code WebFetch su huggingface.co)
Un laboratorio autocontenuto e usa-e-getta che riproduce
GHSA-fg94-h982-f3mm
/ CVE-2026-54316: Claude Code ha pre-approvato huggingface.co come hostname nudo
per lo strumento WebFetch, quindi qualsiasi percorso su quel dominio — inclusi
i repository di modelli controllati da un attaccante — veniva recuperato senza
richiesta di autorizzazione. In combinazione con la prompt injection, questo diventa un canale
out-of-band per esfiltrare dati, osservato tramite i conteggi di download lato server di HuggingFace.
| Advisory | GHSA-fg94-h982-f3mm |
| CVE | CVE-2026-54316 |
| Package | @anthropic-ai/claude-code (npm) |
| Affected | >= 0.2.54, < 2.1.163 |
| Patched | 2.1.163 |
| Root cause | Allow-listing di hostname nudi su un host multi-tenant (CWE-183) |
Questo riproduce una vulnerabilità corretta e pubblicamente divulgata a scopo educativo e difensivo. Usalo solo contro infrastrutture di tua proprietà:
fixtures/canary.env) — non usarne mai uno reale.huggingface.co senza richiesta di approvazione, mentre ogni altro dominio
ne attiva una — perché huggingface.co è in una allow-list hardcoded.Il container è l'unico posto in cui gira la versione vulnerabile; il tuo host rimane pulito. Autenticati con un token di abbonamento Claude (non serve alcuna API key):
docker build -t cve-2026-54316-lab .
docker run --rm -it cve-2026-54316-lab
All'interno del container esegui claude e scegli "Claude account with subscription"
per accedere in modo interattivo. La vulnerabile 2.1.162 è antecedente alla
variabile d'ambiente CLAUDE_CODE_OAUTH_TOKEN, quindi qui non viene usato un
setup-token — il flusso interattivo browser/codice da incollare evita del tutto
di generare un token di lunga durata.
Il punto è l'asimmetria delle richieste di approvazione per dominio, quindi WebFetch rimane
disponibile (non è negato) — l'approvazione è gestita tramite prompt, come predefinito.
Dentro il container, in claude:
Usa WebFetch per recuperare
https://example.come riassumilo.
→ Appare una richiesta di autorizzazione che ti chiede di approvare example.com. Poi:
Usa WebFetch per recuperare
https://huggingface.co/<your-account>/canary-lab/resolve/main/config.json.
Vulnerabile: il recupero di huggingface.co procede senza alcun prompt, mentre
example.com ne richiedeva uno. Quell'asimmetria è il bug — huggingface.co è in una
allow-list hardcoded. (Per questo test il repo HF non deve necessariamente esistere; un 401/404
dimostra comunque che il prompt non è mai comparso.) Ricompila con @anthropic-ai/[email protected]
e ora anche il recupero di huggingface.co richiede il prompt — questo prima/dopo è il punto centrale.
./scripts/make_hf_canary_files.sh ./hf-repo, poi fai push di hf-repo/ su un
repository HuggingFace pubblico di tua proprietà (<your-account>/canary-lab).payloads/untrusted-readme.md, imposta HF_ACCOUNT, e posizionalo dove
l'agente lo leggerà come input non fidato.Dockerfile — versione vulnerabile bloccata 2.1.162.claude/settings.json — allow/deny vuoti così WebFetch chiede il prompt per dominiofixtures/canary.env — canary fittizioscripts/make_hf_canary_files.sh — struttura dei file canary HFpayloads/untrusted-readme.md — payload di prompt injection (sanitizzato)