Fuite de clé maîtresse LiteLLM : comment un jeton GitHub non révoqué a permis un piratage de la chaîne d’approvisionnement
Apollinaire Monteclair
Fuite de clé maîtresse LiteLLM : un incident qui interroge la gestion des secrets
Selon une analyse publiée par l’équipe de LiteLLM, une simple clé maîtresse accidentellement exposée sur GitHub en mai 2026 a conduit à l’une des attaques les plus sophistiquées de la chaîne d’approvisionnement logicielle de l’année. Le 21 octobre 2026, une version malveillante du package Python LiteLLM (1.107.0) a été publiée sur PyPI, Docker Hub et GitHub Container Registry, après qu’un attaquant a pris le contrôle de jetons d’accès ayant les droits de propriétaire de l’organisation. Ce n’est pas une faille zero-day, mais la conséquence d’un manquement aux procédures de révocation des clés, un écueil que trop d’organisations sous-estiment encore. Cet article revient en détail sur le déroulement de l’attaque, les techniques employées et les enseignements pour sécuriser votre propre chaîne de livraison.
L’origine de la brèche : une clé maîtresse exposée sur GitHub
Le 27 mai 2026, un collaborateur de LiteLLM a commis un fichier de configuration dans le dépôt public LiteLLM-Labs/lite-harness. Ce fichier contenait la clé maîtresse (master key) d’un déploiement de la plateforme LiteLLM Agent. « L’erreur a été rapidement identifiée, le commit a été écrasé par un force-push, et les clés exposées ont été marquées comme devant être révoquées. Pourtant, la révocation de la clé maîtresse n’a pas eu lieu », expliquent Oliver Jensen et Mateo Wang, développeurs de LiteLLM.
« La clé maîtresse n’a jamais été révoquée. Cela a permis à un attaquant de l’utiliser pour accéder à la plateforme Agent près de cinq mois plus tard. » - Oliver Jensen et Mateo Wang, LiteLLM
Le 10 octobre 2026, l’adresse IP 69.48.229[.]143 a utilisé cette clé non révoquée pour s’authentifier sur la plateforme Agent. Une fois à l’intérieur, l’attaquant a extrait un jeton OAuth GitHub CLI que le service utilisait pour permettre aux agents de soumettre des pull requests. Ce jeton était « non réduit dans ses droits » (not scoped down) et associé au compte propriétaire de l’organisation GitHub.
Les conséquences immédiates du vol de jeton
Avec ce jeton, l’attaquant disposait d’un accès de niveau « propriétaire » à tous les dépôts de l’organisation BerriAI. Une liberté quasi totale pour lire, écrire et modifier le code, les workflows et les secrets. La suite de l’incident montre comment cet accès a été exploité de manière méthodique et discrète.
Chronologie de l’attaque : du vol de jeton à la publication malveillante
Les équipes de sécurité de LiteLLM, appuyées par les chercheurs de Socket et de Microsoft, ont reconstitué la séquence exacte des opérations. Voici les étapes clés, présentées sous forme de tableau pour plus de clarté :
| Date et heure (UTC) | Action réalisée | Remarque |
|---|---|---|
| 10 oct. 2026, 22:11-22:12 | L’attaquant pousse des commits sur des branches temporaires (ci-tmp-a351cc et ci-tmp-4d8517) pour déclencher des workflows. | Les workflows exfiltrent des jetons GitHub CLI de deux ingénieurs disposant des droits de maintainer. |
| 21 oct. 2026, 10:08-11:08 | L’attaquant modifie le pipeline de release en remplaçant la source du dépôt légitime BerriAI/litellm par un dépôt homographe Berri-AI/litellm. | La protection de branche est contournée. |
| 21 oct. 2026, 11:39-11:40 | La version 1.107.0 de LiteLLM est publiée sur PyPI. | Le package contient du code malveillant. |
| 21 oct. 2026, 11:46 | Les images Docker (Docker Hub et GHCR) sont publiées. | |
| 21 oct. 2026, 11:53-11:54 | Les enregistrements d’exécution (production et staging) sont supprimés. | L’attaquant tente d’effacer ses traces. |
| 21 oct. 2026, 12:06 | La chaîne d’approvisionnement est signalée par Lidor Machluf, chercheur chez Upwind. | Délai de détection : < 1 h après publication. |
| 21 oct. 2026, 13:23 | PyPI place la version 1.107.0 en quarantaine. | |
| 21 oct. 2026, 14:20 | Docker Hub supprime ou repointe les tags v1.107.0, latest, main-latest, main-stable vers des images saines. |
« Dans le fonctionnement normal, une release nécessite le déclenchement par un ingénieur autorisé et l’approbation par un compte spécial verrouillé sur un appareil physique dans nos bureaux. Cette restriction avait été assouplie plus tôt dans la semaine pour accélérer les backports de correctifs, ce qui a permis à l’attaquant d’utiliser un jeton pour déclencher la release et un autre pour l’approuver. » - LiteLLM
Les workflows malveillants détaillés
Les chercheurs de Socket ont retrouvé deux commits malveillants dans l’historique du dépôt, chacun ajoutant un fichier .github/workflows/cache.yml. Ces commits ont été poussés sur des branches éphémères créées à partir d’un commit légitime, puis supprimées quelques minutes après leur utilisation. La technique est redoutable :
- Créer une branche
ci-tmp-<hex>à partir d’un commit récent légitime. - Ajouter un fichier
cache.ymlavec le sujet « ci: bump cache config ». - Le workflow est configuré pour se déclencher sur
push(donc immédiatement exécuté). - Supprimer la branche pour laisser le moins de traces possible dans l’historique.
Les deux workflows avaient pour objectif de collecter et exfiltrer des secrets vers deux endpoints webhook[.]site :
65a42464-3cfa-4b02-a18c-17a6d7b86f374da03473-a3e7-4dc2-a087-9c564b4208e1
Parmi les secrets dérobés : tokens GitHub, API keys pour Linear, Together AI, Anthropic, OpenAI, AWS Bedrock, Tavily, GitGuardian, et même les informations de bases PostgreSQL (chaîne de connexion, mot de passe) ou encore l’adresse Redis avec le port et le mot de passe d’authentification. Le second workflow ajoutait la capture du Playwright storage state, offrant un accès authentifié à un compte Linear sans mot de passe ni MFA.
« Un token GitHub et une clé privée d’application GitHub sont des identifiants directs pour la plateforme hébergeant le dépôt, pas pour un service tiers. Une clé API GitGuardian donne un accès à la plateforme de scan de secrets elle-même, ce qui permettrait à l’attaquant de manipuler les alertes qui auraient normalement détecté cette activité. » - Karlo Zanki, chercheur chez Socket
Les mécanismes du malware : collecte de credentials et backdoor
Le code malveillant embarqué dans la version 1.107.0 de LiteLLM ne se contentait pas d’exfiltrer les secrets pendant la phase de build. Une fois installé sur les systèmes des clients, il mettait en œuvre deux modes d’exécution distincts :
Un module de collecte de credentials (credential harvesting) : il ciblait les fichiers de configuration des développeurs (SSH, Git, GitLab), les variables d’environnement, les tokens npm, pip, Yarn, Maven, Gradle, Composer, RubyGems, Cargo, ainsi que les sessions de navigateur. Toutes ces données étaient compressées puis envoyées à l’URL
litellm[.]dev/healthcheckvia une requête HTTP POST. Ce domaine avait été enregistré le 13 octobre 2026, soit huit jours avant la publication malveillante.Une backdoor orientée Unix : lancée en tâche de fond, elle interrogeait toutes les heures un serveur distant pour récupérer et exécuter un code arbitraire fourni par l’attaquant.
Ce qui rend cette attaque particulièrement dangereuse, c’est que les fichiers de démarrage (startup files) étaient placés en dehors du répertoire de l’application LiteLLM. Ainsi, même si le module LiteLLM lui-même n’était pas importé par une application, le simple fait de lancer Python dans un environnement où le package malveillant avait été installé activait le code nuisible. Comme l’a souligné l’équipe de recherche Microsoft : « Supprimer les fichiers de l’application ne suffisait pas : les composants de démarrage malveillants demeuraient actifs. »
Exemple concret : impact sur un environnement CI typique
Imaginons une entreprise française utilisant LiteLLM comme passerelle LLM dans son pipeline CI. Le package malveillant est installé via pip install litellm==1.107.0 (ou mis à jour automatiquement). Dès la prochaine exécution d’un job CI, même sans appeler explicitement LiteLLM, le script de démarrage est exécuté. En quelques secondes, les secrets GitHub, les clés SSH, et les jetons d’accès aux APIs sont aspirés et transmis à l’attaquant. La backdoor permet ensuite un accès permanent pour modifier les workflows, injecter du code dans d’autres dépôts, ou étendre l’attaque à des fournisseurs tiers.
Enseignements pour la sécurité des chaînes d’approvisionnement
Cet incident n’est pas le premier du genre, mais il illustre avec force plusieurs lacunes organisationnelles que toute équipe de sécurité devrait corriger sans attendre.
1. La révocation immédiate et complète des secrets exposés
L’erreur initiale - un commit accidentel - est humaine et probablement inévitable. Ce qui est répréhensible, c’est l’absence de révocation systématique une fois l’exposition connue. La clé maîtresse n’a jamais été désactivée, ce qui a offert une fenêtre d’attaque de plusieurs mois. Selon une étude de GitGuardian (2025), 70 % des secrets exposés ne sont pas révoqués dans les 30 jours suivant leur détection. Un chiffre alarmant qui explique la récurrence des fuites exploitées.
2. La réduction des droits des jetons d’accès
Le jeton GitHub OAuth volé était associé au compte propriétaire de l’organisation, sans aucune limitation de périmètre. Les bonnes pratiques recommandent de toujours utiliser des fine-grained tokens avec les permissions minimales nécessaires, et de les associer à des machines de service dédiées, pas à des comptes humains.
3. La protection des workflows et des pipelines
L’assouplissement temporaire des règles d’approbation des releases (passage de « deux approbations dont une depuis un dispositif physique » à « deux approbations quelconques ») a grandement facilité l’attaque. Les pipelines critiques doivent bénéficier de contrôles robustes : signature des commits, approbation multi-facteur, et vérification de l’intégrité du code source avant publication.
4. La surveillance des branches éphémères et des workflows suspects
Les branches ci-tmp-<hex> existant moins de cinq minutes passent souvent sous les radars. L’utilisation d’outils de détection d’anomalies (comme les solutions de security-as-code) permet d’alerter sur la création massive de branches temporaires associées à des workflows d’exfiltration.
Mesures de remédiation recommandées
Face à ce type de menace, les recommandations de l’ANSSI et du NIST s’imposent. Voici une liste d’actions concrètes à intégrer d’urgence dans votre plan de sécurisation :
- Auditer et révoquer tous les secrets : lancez une campagne de rotation de l’ensemble des jetons, clés et mots de passe ayant pu être exposés (directement ou indirectement). Utilisez un service de secrets scanning (GitGuardian, truffleHog) pour détecter les fuites passées.
- Appliquer le principe du moindre privilège : pour les comptes de service, créez des jetons avec les seules permissions nécessaires (par exemple, un jeton ne pouvant que déclencher des workflows, sans droit d’écriture sur le code).
- Renforcer l’authentification des pipelines : imposez une approbation multi-facteur pour toute release, idéalement avec une clé matérielle (YubiKey, TPM).
- Surveiller les branches et les actions GitHub : mettez en place des alertes sur les modifications des fichiers
.github/workflows/et sur la création de branches sans pull request associée. - Isoler les environnements CI : utilisez des runners éphémères, sans accès persistant aux secrets, et nettoyez les caches régulièrement.
- Former les équipes : sensibilisez les développeurs aux risques de fuite de secrets dans les commits, et imposez des hooks de pré-commit (comme
git-secrets) pour bloquer les fuites avant le push. - Prévoir un plan de réponse aux incidents : testez régulièrement la procédure de révocation des clés et la communication en cas de compromission.
« La clé maîtresse non révoquée est un échec de processus, pas un échec technique. Les outils existent, mais les organisations ne les appliquent pas toujours. » - Analyse d’un expert indépendant en sécurité logicielle
Conclusion : renforcer la résilience face aux attaques de la chaîne d’approvisionnement
L’attaque contre LiteLLM démontre que la fuite de clé maîtresse n’est que le point de départ d’une chaîne d’événements qui peut conduire à une compromission totale de la chaîne de livraison logicielle. La rapidité de la réaction (signalement moins d’une heure après la publication) a limité l’impact, mais de nombreux clients ont tout de même exécuté du code malveillant.
Pour les responsables sécurité français, cet incident doit servir de catalyseur pour revoir la gouvernance des secrets, la robustesse des pipelines CI/CD et la formation des équipes. En 2026, le paysage des menaces ne laisse plus de place à la négligence : une clé non révoquée, c’est une porte grande ouverte. Adoptez sans attendre les bonnes pratiques mentionnées ici, et surtout, n’oubliez pas que la sécurité de la chaîne d’approvisionnement est l’affaire de tous - développeurs, ops et RSSI.