Fuite de clé maître LiteLLM : comment des jetons GitHub ont été volés pour détourner le pipeline de release
Aurélien Fontevive
En octobre 2026, la bibliothèque Python LiteLLM, passerelle open source pour les modèles de langage (LLM), a été victime d’une compromission majeure de sa chaîne d’approvisionnement. Un adversaire a réussi à publier sur PyPI une version malveillante du paquet (v1.107.0) après avoir exploité une clé maître divulguée accidentellement cinq mois plus tôt. Cet incident expose les failles persistantes dans la gestion des secrets, la révocation des tokens et la sécurité des pipelines CI/CD. Nous décryptons la chronologie, les techniques employées et les leçons à retenir pour toute organisation utilisant des workflows automatisés.
Fuite d’une clé maître LiteLLM : une erreur aux conséquences durables
Le 27 mai 2026, un développeur de LiteLLM commet un fichier de configuration dans le dépôt public litetllm-labs/lite-harness. Ce fichier contient, par inadvertance, la clé maître du déploiement interne de l’Agent Platform, l’outil d’orchestration d’agents utilisé par l’équipe. L’erreur est vite repérée : le commit est force-pushed et la clé est identifiée comme devant être révoquée. Pourtant, cette révocation n’a jamais eu lieu pour la clé maître. Les développeurs Oliver Jensen et Mateo Wang l’ont reconnu : « L’erreur a été rapidement identifiée, le commit remplacé, et nous avons identifié les clés exposées comme nécessitant une révocation. Cependant, la révocation de la clé maître n’a pas eu lieu. »
Ce défaut de procédure a offert à un attaquant une fenêtre de tir de plusieurs mois. Alors que les clés secondaires ont été révoquées, la clé maître - dont le niveau de privilège est maximal - est restée active. Un oubli qui a permis la compromission ultérieure.
« La clé maître est restée active alors qu’elle aurait dû être immédiatement révoquée. Cet oubli est à l’origine de toute la chaîne d’attaque. » - LiteLLM, analyse post-incident
Chronologie de l’attaque : une exécution méthodique
L’attaquant, opérant depuis l’adresse IP 69.48.229[.]143, a utilisé la clé maître non révoquée le 10 octobre 2026 pour accéder à l’Agent Platform LiteLLM. Il y a extrait un token OAuth GitHub CLI que la plateforme utilisait pour permettre à des agents cloud auto-hébergés de soumettre des pull requests vers les dépôts GitHub. Or, ce token n’était pas scopé (réduit dans ses permissions) : il était associé au compte propriétaire de l’organisation GitHub de LiteLLM, offrant un accès de niveau propriétaire à tous les dépôts.
Voici la séquence exacte des événements rapportés par LiteLLM, confirmée par les analystes de Socket et Upwind :
| Date (UTC) | Événement |
|---|---|
| 10 octobre 2026, 22:11-22:12 | Commit dans des branches éphémères (ci-tmp-*) sur des dépôts internes pour lancer des workflows de récolte de tokens. |
| 10 octobre 2026, 22:12 | Suppression des branches et des traces. |
| 21 octobre 2026, 10:08-11:08 | Contournement de la protection de branche ; modification du pipeline de release pour pointer vers le dépôt miroir malveillant Berri-AI/litellm au lieu de BerriAI/litellm. |
| 21 octobre 2026, 11:39-11:40 | Publication de la version 1.107.0 sur PyPI. |
| 21 octobre 2026, 11:46 | Publication d’images Docker sur Docker Hub et GHCR. |
| 21 octobre 2026, 11:53-11:54 | Suppression des enregistrements des runs de production et staging. |
| 21 octobre 2026, 12:06 | Signalement de l’attaque par le chercheur Lidor Machluf (Upwind). |
| 21 octobre 2026, 13:23 | PyPI met en quarantaine la version 1.107.0. |
| 21 octobre 2026, 14:20 | Docker Hub supprime ou réaffecte les tags v1.107.0, latest, main-latest et main-stable vers des images vierges vérifiées. |
Ce tableau montre la rapidité d’exécution : l’attaquant n’a eu besoin que de quelques heures pour accomplir l’ensemble des opérations, et la détection a été possible grâce à un chercheur externe.
Contournement des protections de release
En temps normal, la construction et la publication d’une release nécessitent le déclenchement par un ingénieur autorisé, puis l’approbation par un compte spécial verrouillé sur un périphérique physique dans les locaux de LiteLLM. Cependant, cette restriction avait été assouplie temporairement pour permettre des releases plus fréquentes et des rétroportages de correctifs. Deux ingénieurs pouvaient désormais déclencher et approuver une release. L’attaquant a utilisé un token volé pour déclencher la release (après avoir redirigé le deployer vers son dépôt malveillant) et un autre token pour l’approuver.
Analyse des workflows malveillants : un vol de secrets en deux temps
Les chercheurs de Socket ont retrouvé deux commits malveillants, chacun ajoutant un workflow .github/workflows/cache.yml. Le premier a été poussé le 10 octobre 2026 à 22:11:45 UTC, suivi d’un second le 12 octobre. Les deux ont été poussés sur des branches éphémères nommées ci-tmp-<hex> (par exemple ci-tmp-a351cc et ci-tmp-4d8517), créées à partir d’un commit légitime récent pour paraître anodines, puis supprimées après exécution.
« Aucun des deux commits n’a été poussé sur une branche qui existe encore. Tous deux ont été poussés sur des branches à courte durée de vie qui ont été créées, utilisées et supprimées en quelques minutes. » - Karlo Zanki, chercheur chez Socket
Chaque workflow est déclenché sur push (on: [push]), ce qui le lance automatiquement dès son ajout. Le premier workflow récolte les tokens GitHub, les clés API de l’espace Linear, du déploiement LiteLLM, de Together AI, ainsi que l’identifiant et la clé de signature d’une GitHub App. Le second étend la collecte à des secrets supplémentaires : clés API pour Anthropic, OpenAI, AWS Bedrock, Tavily, et même la clé API de GitGuardian, plateforme de secret scanning. Il capture aussi un état de session Playwright, des informations de base de données PostgreSQL (chaîne de connexion, mot de passe) et les paramètres Redis.
Ces données sont exfiltrées vers deux endpoints webhook[.]site distincts :
webhook[.]site/65a42464-3cfa-4b02-a18c-17a6d7b86f37webhook[.]site/4da03473-a3e7-4dc2-a087-9c564b4208e1
La présence de la clé API GitGuardian est particulièrement inquiétante. Comme le souligne Zanki : « GITGUARDIAN_API_KEY est une accréditation pour la plateforme de secret scanning elle-même, ce qui donne à un attaquant une visibilité et potentiellement un contrôle sur les alertes qui auraient pu détecter cette activité. »
Capacités du paquet malveillant : un vol multi-cible et une porte dérobée
La version 1.107.0 livrée sur PyPI contenait des fichiers conçus pour s’exécuter automatiquement au démarrage de Python, même si LiteLLM n’était pas importé. Les mécanismes d’exécution se divisent en deux branches :
Module de vol d’identifiants : il cible les tokens d’authentification des outils de développement (SSH, Git, GitLab), des applications d’IA, des environnements cloud et des navigateurs web. Il récolte également les variables d’environnement, les identifiants de package managers (npm, PyPI, pip, Yarn, Maven, Gradle, Composer, RubyGems, Cargo). Les données sont compressées et envoyées en POST vers
litellm[.]dev/healthcheck(domaine enregistré le 13 octobre 2026).Porte dérobée orientée Unix : un processus en arrière-plan est lancé pour récupérer et exécuter du code arbitraire fourni par l’attaquant toutes les heures.
« Ensemble, ces mécanismes étendent l’exposition potentielle au-delà des déploiements actifs de LiteLLM : simplement lancer Python dans un environnement affecté pouvait activer le code malveillant, même si LiteLLM n’était jamais importé. » - Équipe de recherche Microsoft Security
Cette particularité rend le nettoyage plus complexe : les fichiers de démarrage se trouvent en dehors du répertoire de l’application, donc une simple désinstallation de LiteLLM ne suffit pas à éliminer la menace.
Implications pour la sécurité des chaînes d’approvisionnement logicielles
L’incident LiteLLM illustre plusieurs lacunes classiques mais toujours d’actualité dans la sécurisation des pipelines logiciels :
- Gestion des secrets : une clé maître exposée doit être révoquée immédiatement. Le fait que la révocation n’ait pas eu lieu malgré l’identification montre l’importance d’automatiser ce processus.
- Permissions trop larges : le token OAuth GitHub CLI associé au compte propriétaire n’était pas scopé. Tout token utilisé dans un pipeline devrait avoir les privilèges minimaux nécessaires, idéalement au niveau du dépôt et non de l’organisation.
- Absence de rotation fréquente : les clés maîtres et tokens de déploiement devraient être renouvelés régulièrement.
- Faiblesse des protections CI/CD : l’assouplissement temporaire des règles d’approbation à deux ingénieurs a facilité l’attaque. Les contrôles devraient rester stricts même en période de release accélérée.
- Manque de détection des branches éphémères : l’attaquant a créé des branches
ci-tmp-*qui n’ont laissé quasiment aucune trace dans l’historique standard. Les outils de surveillance doivent être capables de détecter ces artefacts.
Recommandations pratiques pour les équipes de développement
Pour éviter une compromission similaire, voici les mesures essentielles à mettre en œuvre :
- Automatiser la révocation des secrets exposés : tout secret détecté comme divulgué doit être immédiatement révoqué, sans exception. Utilisez des outils comme GitGuardian, TruffleHog, ou les alertes GitHub.
- Scoper les tokens GitHub : utilisez des fine-grained personal access tokens avec des permissions limitées aux dépôts nécessaires. Évitez les tokens au niveau de l’organisation.
- Auditer régulièrement les permissions des workflows : les workflows CI/CD ne devraient pas avoir accès aux secrets qui ne sont pas strictement nécessaires à leur exécution.
- Imposer des approbations multiples et matérielles : les releases critiques doivent nécessiter une approbation depuis un poste de travail sécurisé, idéalement avec une clé physique (YubiKey).
- Mettre en place une détection des branches éphémères : configurez des alertes sur les branches créées et supprimées rapidement, surtout si elles contiennent des workflows.
- Renforcer la sécurité des runner CI : utilisez des runners hébergés par GitHub ou des environnements éphémères, et limitez l’accès réseau sortant.
- Réaliser une revue de code des workflows : tout nouveau workflow devrait être soumis à une revue manuelle avant déploiement, en particulier ceux qui manipulent des secrets.
Conclusion : une chaîne d’approvisionnement sous tension
L’attaque contre LiteLLM démontre une fois de plus qu’une seule erreur de configuration, couplée à une révocation non réalisée, peut ouvrir la voie à une compromission massive de la chaîne d’approvisionnement. Le vol de tokens GitHub, la redirection du pipeline de release et l’injection de code malveillant dans PyPI et Docker Hub ont été possibles grâce à une combinaison de négligences techniques et procédurales. Les organisations qui utilisent des passerelles LLM ou tout autre logiciel open source doivent tirer les leçons de cet incident : la sécurité des pipelines CI/CD ne peut plus être une réflexion après-coup. Une politique rigoureuse de gestion des secrets, des permissions minimales et une détection proactive des anomalies sont les piliers d’une défense efficace contre ce type de menaces.