
Labo de reproduction pour CVE-2026-54316 (Claude Code WebFetch huggingface.co bare-hostname contournement de permission / exfiltration)
Un laboratoire autonome et jetable qui reproduit
GHSA-fg94-h982-f3mm
/ CVE-2026-54316 : Claude Code a pré-approuvé huggingface.co comme nom d'hôte nu
pour l'outil WebFetch, de sorte que tout chemin sur ce domaine — y compris
les dépôts de modèles contrôlés par un attaquant — était récupéré sans invite
d'autorisation. Combiné à une injection d'invite, cela devient un canal hors bande
pour l'exfiltration de données, observé via les compteurs de téléchargement côté serveur de HuggingFace.
| Avis | GHSA-fg94-h982-f3mm |
| CVE | CVE-2026-54316 |
| Paquet | @anthropic-ai/claude-code (npm) |
| Versions affectées | >= 0.2.54, < 2.1.163 |
| Version corrigée | 2.1.163 |
| Cause racine | Liste blanche de nom d'hôte nu sur un hôte multi-locataire (CWE-183) |
Ceci reproduit une vulnérabilité corrigée et divulguée publiquement à des fins éducatives et défensives. Utilisez-le uniquement contre une infrastructure vous appartenant :
fixtures/canary.env) — n'utilisez jamais un vrai.huggingface.co sans invite d'approbation, alors que tout autre domaine en déclenche
une — parce que huggingface.co se trouve dans une liste blanche codée en dur.Le conteneur est le seul endroit où la version vulnérable s'exécute ; votre hôte reste propre. Authentifiez-vous avec un jeton d'abonnement Claude (aucune clé API nécessaire) :
docker build -t cve-2026-54316-lab .
docker run --rm -it cve-2026-54316-lab
À l'intérieur du conteneur, exécutez claude et choisissez « Compte Claude avec abonnement »
pour vous connecter de manière interactive. La version vulnérable 2.1.162 est antérieure à la
variable d'environnement CLAUDE_CODE_OAUTH_TOKEN, donc un setup-token n'est pas utilisé ici —
le flux interactif navigateur/coller-code évite complètement de créer un jeton de longue durée.
Le point est l'asymétrie de l'invite d'approbation par domaine, donc WebFetch est laissé
disponible (il n'est pas refusé) — l'approbation est gérée par des invites, par défaut.
À l'intérieur du conteneur, dans claude :
Utilisez WebFetch pour récupérer
https://example.comet résumez-le.
→ Une invite d'autorisation apparaît vous demandant d'approuver example.com. Ensuite :
Utilisez WebFetch pour récupérer
https://huggingface.co/<votre-compte>/canary-lab/resolve/main/config.json.
Vulnérable : la récupération de huggingface.co se déroule sans invite, tandis que
example.com en nécessitait une. Cette asymétrie est le bogue — huggingface.co se trouve dans une
liste blanche codée en dur. (Le dépôt HF n'a pas besoin d'exister pour ce test ; un code 401/404
prouve toujours que l'invite ne s'est jamais déclenchée.) Reconstruisez avec
@anthropic-ai/[email protected] et la récupération de huggingface.co invite désormais aussi —
cet avant/après est le titre.
./scripts/make_hf_canary_files.sh ./hf-repo, puis poussez hf-repo/ vers un
dépôt HuggingFace public que vous possédez (<votre-compte>/canary-lab).payloads/untrusted-readme.md, définissez HF_ACCOUNT, et placez-le là où
l'agent le lira en tant qu'entrée non fiable.Dockerfile — version vulnérable épinglée 2.1.162.claude/settings.json — autorisation/refus vide afin que WebFetch invite par domainefixtures/canary.env — canary facticescripts/make_hf_canary_files.sh — disposition des fichiers canary HFpayloads/untrusted-readme.md — charge utile d'injection d'invite (nettoyée)