Le 21 octobre 2026, la version 1.107.0 de LiteLLM a diffusé un logiciel malveillant via PyPI et des images Docker officielles. Le piège dépassait largement l’utilisation du proxy : démarrer Python dans un environnement infecté pouvait suffire à déclencher un vol d’identifiants. Pour les équipes concernées, la priorité n’est donc pas de vérifier que LiteLLM répond toujours.
Il faut d’abord retrouver les installations exposées sans exécuter de code suspect, déterminer quels secrets étaient accessibles, reconstruire les systèmes concernés et révoquer les anciennes clés. Une précaution supplémentaire s’impose pour le proxy : une mauvaise rotation de sa clé maître peut rendre illisibles les identifiants enregistrés en base.
Trois points clés
- Version suspecte : litellm==1.107.0 sur PyPI, ainsi que plusieurs images Docker diffusées le 21 octobre 2026.
- Premier réflexe : contrôler les fichiers et les historiques depuis un système sain, sans lancer python ni pip dans l’environnement suspect.
- Après exposition : reconstruire, révoquer les secrets accessibles et adapter la rotation de la clé maître à la configuration du chiffrement.
LiteLLM 1.107.0 a été piégé, voici ce qui est réellement concerné
Entre 11 h 39 et 13 h 23 UTC le 21 octobre, sept distributions malveillantes de litellm==1.107.0 ont circulé sur PyPI. Sur Docker Hub, les tags v1.107.0, latest, main-latest et main-stable ont renvoyé vers une image compromise entre 11 h 46 et 14 h 20 UTC. Ces fenêtres de publication, détaillées dans le bulletin de sécurité de LiteLLM, ne signifient pas qu’un conteneur téléchargé pendant l’incident est devenu sain après 14 h 20. Il peut toujours dormir dans un registre privé ou un cache.
Le paquet contenait notamment des mécanismes de démarrage Python utilisant un fichier .pth et sitecustomize.py. Selon Microsoft Security Research, le code pouvait collecter des clés de fournisseurs IA, des identifiants cloud, des données de connexion et d’autres secrets accessibles à l’utilisateur exécutant Python. Même une application qui n’importait pas LiteLLM pouvait être exposée. Cette passerelle IA multi-modèles centralise souvent plusieurs accès sensibles. L’éditeur indique que sa distribution privée Enterprise n’a pas été touchée par cet incident d’octobre. L’archive du code source sur GitHub ne contenait pas les fichiers malveillants : l’attaque a visé les artefacts distribués lors de la publication.
Comment vérifier son installation sans réveiller le programme malveillant
Commencez par l’inventaire, pas par un test. Recherchez LiteLLM dans les fichiers requirements.txt, poetry.lock, uv.lock, les journaux de construction, les manifestes Kubernetes, les images Docker et les environnements virtuels. Une dépendance indirecte peut aussi l’avoir introduit. Notez le nom de l’hôte, la période d’installation et le contexte : poste développeur, runner CI/CD ou proxy en production.
Évitez `pip show litellm` et `python -c ‘import litellm’` sur le système suspect. Les mécanismes malveillants pouvaient s’exécuter au démarrage de l’interpréteur ; pip repose lui aussi sur Python. Si la machine a pu être contaminée, examinez son disque depuis un poste de confiance ou un volume monté en lecture seule. Lisez seulement les fichiers texte. Un test fonctionnel positif ne prouverait pas l’absence de vol.
Dans un environnement Python, cherchez le répertoire litellm-1.107.0.dist-info sous site-packages, puis lisez son fichier METADATA comme un document ordinaire. Inspectez également les caches de gestionnaires de paquets. Téléchargement et exécution ne sont pas équivalents : une archive conservée dans un cache ne signifie pas nécessairement qu’un interpréteur a exécuté sa charge. En revanche, la présence d’une installation infectée utilisée pour lancer Python doit être traitée comme un incident.
Pour Docker, examinez les dates de récupération des images, les digests et les historiques de déploiement. LiteLLM a identifié le digest d’index Docker Hub sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e. Ne vous fiez donc pas au seul nom latest, désormais modifié. Vérifiez quelle image exacte a été exécutée, et non celle à laquelle le tag renvoie aujourd’hui.
Quels indices prouvent une exposition, et lesquels ne suffisent pas ?
Les fichiers cook.pth, cook.py et sitecustomize.py figurent parmi les éléments à rechercher, avec les métadonnées de la version compromise. Mais sitecustomize.py peut aussi appartenir à une configuration Python légitime. Comparez donc son contenu, ses dates et son emplacement aux indicateurs publiés. Recherchez également /tmp/remote_code_loader.lock et /tmp/.pc_once_72129118c59f5636c0bb, deux traces décrites dans l’analyse technique de Microsoft.
Les journaux réseau peuvent révéler un contact avec le domaine www[.]litellm[.]dev, signalé comme destination d’exfiltration. Faites examiner les traces DNS, proxy, pare-feu et EDR autour de l’installation. Une connexion de sortie correspondante aide à reconstituer l’exécution du programme, mais l’absence de trace ne prouve pas qu’aucun secret n’a été envoyé : les journaux peuvent manquer et les conteneurs éphémères avoir disparu.
Avant d’effacer les fichiers, conservez les preuves utiles selon votre procédure de réponse à incident : horodatages, journaux, images des supports et historique des déploiements. Isolez les machines concernées et évitez d’y relancer les outils habituels. Cette étape aide à distinguer trois situations : le paquet a seulement été téléchargé ; il a été installé ; ou Python et le conteneur infecté ont réellement fonctionné avec des secrets accessibles. Le degré de réponse dépend de ces éléments, sans attendre une preuve parfaite d’exfiltration.
Faut-il simplement réinstaller LiteLLM ? Non, il faut reconstruire
Changer de version ne supprime pas des identifiants déjà volés. Le malware pouvait se déclencher avant le chargement de LiteLLM, collecter des secrets et lancer un autre processus. Sur une machine ayant exécuté le paquet compromis, reconstruisez les environnements virtuels ou les conteneurs depuis une source fiable, plutôt que de vous contenter d’une désinstallation. Vérifiez également les artefacts construits pendant l’incident.
L’alerte d’urgence du 21 octobre conseillait de revenir à 1.106.2. Le journal officiel des versions mentionne depuis des correctifs sur plusieurs branches, notamment 1.106.5 le 27 octobre. Le bon choix reste une version publiée hors de l’incident, vérifiée et compatible avec votre configuration. Figez la version du paquet et les digests d’images.
Ne réintroduisez les clés neuves qu’après avoir rétabli un environnement digne de confiance. Les tests de routage, d’authentification et d’accès aux modèles doivent s’effectuer depuis cette nouvelle installation. Pour un runner CI/CD compromis, inspectez aussi les jetons de déploiement et les images qu’il a publiées. Une reconstruction rétablit l’intégrité du logiciel ; elle ne révoque aucun secret. C’est l’étape suivante qui empêche l’attaquant d’utiliser des accès éventuellement récupérés.
Quelles clés API faut-il révoquer en priorité ?
Dressez la liste de ce que le système pouvait lire : clés OpenAI, Anthropic ou autres fournisseurs, identifiants cloud, DATABASE_URL, tokens CI/CD, clés virtuelles LiteLLM et LITELLM_MASTER_KEY. Depuis un poste sain, créez les nouveaux identifiants dans les consoles officielles ou votre gestionnaire de secrets. Réduisez leurs permissions, basculez les services reconstruits, puis révoquez les anciens. En présence d’une activité suspecte, invalidez d’abord les accès les plus puissants et documentez chaque remplacement. Si la disponibilité l’exige, préparez le basculement avant la révocation, sans prolonger l’exposition.
Les clés fournisseurs et les clés virtuelles LiteLLM n’ont pas le même rôle. Les premières autorisent l’accès aux API des modèles et se renouvellent chez leurs fournisseurs. Les secondes permettent à vos applications de s’authentifier auprès du proxy. Recréez-les pour chaque service, attribuez des droits et limites adaptés, remplacez-les côté client, puis supprimez les anciennes. La documentation LiteLLM sur les clés virtuelles décrit leur gestion. Renouveler la clé du proxy sans révoquer une clé fournisseur exposée laisserait une porte ouverte.
Reste le mot de passe de DATABASE_URL, indépendant des clés des fournisseurs. Renouvelez-le auprès de la base, examinez les comptes autorisés et contrôlez les connexions existantes. Pour les identités cloud, invalidez aussi les sessions ou jetons temporaires concernés : changer un mot de passe de console ne suffit pas toujours. Évitez de copier les secrets en clair dans un ticket ou un terminal partagé. Le bon test final est un appel contrôlé depuis le nouveau proxy, avec des identifiants neufs et des journaux propres.
Clé maître LiteLLM et salt key : éviter de bloquer le proxy
La clé maître réclame davantage de prudence. Avec LITELLM_SALT_KEY configurée, la clé de chiffrement des secrets stockés est distincte de LITELLM_MASTER_KEY. Il est alors possible de remplacer la clé maître dans la configuration et le coffre de secrets, puis de redémarrer toutes les instances. La procédure officielle de rotation avertit dans ce cas de ne pas appeler /key/regenerate avec new_master_key : l’opération risquerait de rendre des identifiants enregistrés illisibles.
Sans `LITELLM_SALT_KEY`, la clé maître peut aussi servir au chiffrement des identifiants conservés en base. Une simple modification de la variable est donc dangereuse. Sauvegardez la base et suivez la migration documentée, notamment via LITELLM_MIGRATE_FROM_MASTER_KEY si elle convient à votre version. Ne changez pas non plus la salt key sans plan de réenregistrement des secrets : LiteLLM précise qu’elle ne se renouvelle pas par une migration ordinaire. Vérifiez enfin la valeur de general_settings.master_key, qui peut primer sur la variable d’environnement.
Après la rotation, comment vérifier qu’aucun accès ne reste ouvert ?
Comparez les consommations API, les appels au proxy et les événements d’authentification avant et après le 21 octobre. Repérez les pics de dépenses, les requêtes depuis des adresses inhabituelles, les nouvelles clés et les ressources cloud inattendues. Vérifiez aussi les jobs de déploiement et leurs artefacts. Une facture normale ne prouve pas l’absence de compromission : certaines utilisations malveillantes génèrent peu de coût.
Consignez les changements dans un registre de remédiation : identifiant du service, propriétaire de la clé, date de révocation et vérification de l’accès. Cela évite qu’une application secondaire continue d’utiliser un ancien secret oublié. La reprise ne se mesure donc pas au seul retour d’une réponse du modèle. Elle est crédible lorsque l’équipe peut identifier l’artefact exécuté, confirmer la reconstruction, documenter les clés remplacées et surveiller les accès qui subsistent. La leçon de LiteLLM tient en une erreur à éviter : lancer Python pour « vérifier rapidement » une installation douteuse. Dans cette affaire, ce geste banal pouvait précisément remettre le voleur au travail.
- Partager l'article :
