système : OPÉRATIONNEL
← retour à tous les hacks
SUPPLY CHAIN CRITICAL

Mini Shai-Hulud : le ver supply-chain qui s'en est pris à l'écosystème IA

Divulgué du 11 au 18 mai 2026, le ver Mini Shai-Hulud a trojanisé plus de 170 paquets npm et PyPI — dont Mistral AI, Guardrails AI et TanStack — et installe une persistance dans Claude Code et VS Code.

2026-05-22 // 8 min affects: tanstack, mistral-ai-python-sdk, guardrails-ai, uipath-sdk, opensearch-js, claude-code, vs-code, openai-macos-deps

Que s’est-il passé

Le 11 mai 2026, l’acteur TeamPCP a commencé à publier des versions trojanisées de paquets npm très utilisés, à commencer par TanStack puis, en quelques heures, le SDK Python de Mistral AI, Guardrails AI, UiPath et OpenSearch. En cinq heures, plus de 400 versions malveillantes réparties sur 172 paquets distincts ont été publiées sur npm et PyPI, pour un cumul historique d’environ 518 millions de téléchargements. Le 12 mai, le code source entièrement weaponisé a été brièvement publié sur des dépôts GitHub publics avant retrait. Une seconde vague, à partir du 18 mai, a compromis plus de 300 paquets @antv via un compte mainteneur détourné. La campagne — surnommée Mini Shai-Hulud par référence au plus grand ver npm de fin 2025 — est suivie sous CVE-2026-45321 (CVSS 9.6) pour le vecteur initial TanStack.

Ce qui justifie un article dédié ici : l’écosystème de tooling IA n’est pas un dommage collatéral, c’est une cible primaire.

Comment ça marche

Le point d’entrée TanStack chaîne trois mauvaises configurations GitHub Actions. L’attaquant fork le dépôt cible sous un compte renommé (zblgg/configuration plutôt que zblgg/router) pour échapper aux recherches sur la liste des forks, ouvre une pull request, et déclenche un workflow pull_request_target. Ce workflow checkout et exécute le code du fork de l’attaquant dans le contexte de confiance du dépôt de base — avec les secrets, un scope id-token: write, et un accès en écriture au cache GitHub Actions. Le fork embarque un store pnpm empoisonné qui se retrouve mis en cache ; les runs CI légitimes suivants tirent ce cache empoisonné et publient sur npm des tarballs trojanisés avec des attestations de provenance valides, puisque la publication a bien eu lieu depuis le pipeline officiel.

Le payload lui-même est modulaire :

# Schéma conceptuel — issu des analyses d'IoC publiques, non exécutable.
# Le post-install malveillant :
#  1. Exfiltre l'environnement vers un C2 (trois canaux redondants).
#  2. Vole : GITHUB_TOKEN, clés AWS IAM, tokens HashiCorp Vault, secrets K8s.
#  3. Forge des tokens de publication npm signés OIDC via id-token: write.
#  4. Installe un service `gh-token-monitor` qui ré-exfiltre les tokens renouvelés.
#  5. Persiste en écrivant dans :
#       ~/.claude/settings.json    # hook Claude Code
#       ~/.vscode/tasks.json       # task runner VS Code
#  6. Si api.github.com renvoie HTTP 40x (token révoqué) :
#       rm -rf ~/                   # [PAYLOAD DESTRUCTIF — CAVIARDÉ]

Les variantes PyPI pour Mistral AI et Guardrails AI embarquent un stealer différent, taillé pour les environnements Python — mêmes C2, mêmes cibles d’exfiltration, mais hooks adaptés. La vague @antv une semaine plus tard a utilisé un identifiant mainteneur volé plutôt qu’un empoisonnement CI, mais le payload post-install appartient à la même famille.

Pourquoi c’est important

Trois éléments distinguent cette campagne d’une attaque supply-chain npm classique.

L’écosystème IA est dans le périmètre. Guardrails AI est par construction une bibliothèque défensive que les applications LLM enroulent autour de leurs appels modèle. Une version trojanisée transforme un garde-fou en canal d’exfiltration sortant, posé exactement à la frontière application/modèle. Le SDK Python de Mistral AI touche tout projet qui appelle l’API Mistral. D’après l’analyse de Rescana, les produits desktop macOS d’OpenAI ont été indirectement affectés via une chaîne de dépendances TanStack.

La persistance vise spécifiquement les agents IA. Écrire dans ~/.claude/settings.json survit à npm uninstall et ré-arme le stealer au prochain lancement de Claude Code. Le même schéma fonctionne contre tout agent qui auto-charge sa configuration au démarrage. L’enveloppe de privilèges de l’agent — accès shell, accès dépôts, accès aux identifiants — devient l’enveloppe de privilèges du ver.

Les attestations de provenance étaient valides. Comme la publication s’est faite depuis le pipeline GitHub Actions légitime, la signature de provenance npm passe les contrôles. Les défenses qui reposent uniquement sur l’attestation ne détectent pas cette attaque.

Défenses

Pas de mitigation côté modèle ici. Les correctifs sont de l’hygiène CI/CD et de la discipline d’identifiants.

  1. Auditez vos lockfiles pour toute version d’un paquet affecté installée après le 29 avril 2026. Utilisez npm audit, Snyk, ou les scanners communautaires (GLPMC/Tanstack-Worm-Detector, omarpr/mini-shai-hulud-ioc-scanner). Traitez toute correspondance comme un incident avéré.
  2. Faites tourner tout ce qui est joignable depuis un poste ou un runner CI compromis : PAT et tokens OAuth GitHub, tokens npm, clés IAM cloud (AWS/GCP/Azure), tokens HashiCorp Vault, secrets Kubernetes de service account.
  3. Restreignez pull_request_target. Ne checkoutez jamais du code de fork sous ce trigger sans un garde repository_owner. Basculez les builds de fork sur pull_request sans secrets.
  4. Épinglez les actions tierces par SHA, pas par tag. Épinglez aussi les consommateurs internes.
  5. Scopez id-token: write au job minimal, jamais au niveau workflow.
  6. Nettoyez la persistance Claude Code et VS Code. Inspectez ~/.claude/settings.json et ~/.vscode/tasks.json (et leurs copies locales au workspace) à la recherche d’entrées de hook que vous n’avez pas écrites. Les scanners d’IoC repèrent les variantes connues.
  7. Re-scopez les caches CI par branche. Le durcissement de TanStack a inclus la suppression de tous les caches et l’isolation des builds de fork côté fork. Reproduisez ce schéma.

Statut

CibleVecteurDivulgationCorrection / Nettoyage
TanStack (@tanstack/*)Empoisonnement cache CI via pull_request_target2026-05-11Versions malveillantes retirées ; CI restructurée
Mistral AI Python SDKRelease PyPI trojanisée2026-05-11Versions affectées yankées, nouvelle release republiée
Guardrails AIRelease PyPI trojanisée2026-05-11Versions affectées yankées
UiPath, OpenSearch-jsReleases npm trojanisées2026-05-11Retirées
@antv/* (300+ paquets)Compte mainteneur compromis2026-05-18Mainteneur réinitialisé, paquets nettoyés
CVE-2026-45321 (chaîne CI TanStack)2026-05-12CVSS 9.6 — mitigations publiées

À retenir : l’écosystème de tooling IA est désormais considéré comme une cible supply-chain de premier ordre, sur ses propres mérites. Un ver qui s’installe dans ~/.claude/settings.json n’a pas besoin de casser le modèle — il possède l’agent.

Sources