- Journal de réponse minute par minute documentant la détection et l’analyse en temps réel de l’infection par le paquet malveillant LiteLLM 1.82.8 distribué via PyPI
- L’infection s’est produite lors de la mise à jour automatique de Cursor IDE ; l’exécution du fichier
litellm_init.pth a entraîné le vol d’identifiants et l’infection du système
- Le code malveillant a mené des actions multiples, dont la collecte de clés SSH et d’identifiants cloud, des tentatives de propagation dans Kubernetes et la création d’une fork bomb
- L’incident a été signalé immédiatement à l’équipe sécurité de PyPI et aux mainteneurs de LiteLLM, aboutissant à la mise en quarantaine du paquet et à l’enregistrement d’un CVE
- Des outils d’analyse de code basés sur l’IA comme Claude Code ont joué un rôle clé dans la détection de l’attaque, mettant en lumière la nécessité de renforcer la sécurité de la chaîne d’approvisionnement de l’écosystème IA
Journal de réponse à l’attaque de la chaîne d’approvisionnement de LiteLLM
- La version LiteLLM 1.82.8 a été identifiée comme un paquet malveillant distribué via PyPI, et ce document constitue un journal de réponse minute par minute couvrant le processus allant de la détection de l’infection à sa mise en quarantaine
- L’infection s’est produite pendant la mise à jour automatique de Cursor IDE ; parmi les dépendances installées via Claude Code et le gestionnaire de paquets uv, le fichier
litellm_init.pth s’est exécuté et a provoqué l’infection du système
- L’attaque combinait plusieurs comportements, notamment le vol d’identifiants, l’installation d’une persistance, des tentatives de propagation dans Kubernetes et une fork bomb
- L’incident a été immédiatement signalé à l’équipe sécurité de PyPI et aux mainteneurs de LiteLLM, ce qui a conduit à la mise en quarantaine du paquet et à l’attribution d’un CVE
- Des outils d’analyse de code basés sur l’IA ont joué un rôle central dans la détection et l’analyse en temps réel des comportements malveillants
Détection initiale et signes d’anomalie système
- Vers 11:13 UTC, plus de 11 000 processus Python ont été créés sur un ordinateur portable macOS, plaçant le système dans un état de blocage
- Des commandes de la forme
exec(base64.b64decode('...')) étaient exécutées en boucle, saturant le CPU et la mémoire
- Après un arrêt forcé puis un redémarrage, aucune trace liée à la persistance n’a été обнаружée
- Au départ, le phénomène a été interprété comme une boucle non malveillante, potentiellement causée par une boucle interne de Claude Code ou une erreur dans un script
uv run
- Par la suite, des captures d’écran
htop et les journaux ont confirmé l’exécution répétée d’un script Python encodé en base64
Identification de l’origine de l’infection
- Vers 11:40, le fichier
litellm_init.pth a été découvert dans des outils Python installés, confirmant un comportement malveillant
- Les fichiers
.pth s’exécutent automatiquement au démarrage de Python et s’appliquent donc à tous les processus Python
- Il collectait des clés SSH, identifiants cloud, mots de passe de bases de données, variables d’environnement et historiques de shell
- Les données collectées étaient chiffrées en RSA puis envoyées à
https://models.litellm.cloud/
- Il a tenté d’installer une persistance via
~/.config/sysmon/sysmon.py, mais l’opération a été interrompue par le redémarrage forcé
- L’infection s’est produite lors de la mise à jour automatique de Cursor IDE (10:58 UTC)
- L’extension
futuresearch-mcp-legacy a téléchargé litellm 1.82.8 via uvx
- Cette version n’existait que sur PyPI et ne correspondait à aucun tag de release GitHub
- L’horodatage d’upload sur PyPI indiquait 10:52 UTC, soit juste avant l’infection
Structure du code malveillant
- Étape 1 (
litellm_init.pth) : exécution automatique au démarrage de Python, décodage puis exécution d’une charge utile encodée en base64
- Étape 2 : inclusion d’une clé publique RSA pour chiffrer les données volées
- Étape 3 (
B64_SCRIPT) : collecte et exfiltration effectives des identifiants
- Installation de persistance : tentative d’enregistrement de
sysmon.py comme service systemd
- Code de propagation Kubernetes : tentative de création de pods privilégiés sur chaque nœud à l’aide de l’image
alpine:latest
- Cause de la fork bomb : l’appel
subprocess.Popen([sys.executable, "-c", ...]) réexécutait le fichier .pth dans les processus enfants, provoquant une boucle infinie
Étendue de l’impact et mesures de réponse
-
Identifiants exposés
- Clés SSH, identifiants GCloud et Kubernetes, clés API dans les fichiers
.env, mots de passe Supabase, ClickHouse et Grafana, etc.
- Mesures immédiates recommandées
- Faire tourner tous les identifiants SSH et cloud
- Réémettre les secrets présents dans
.env et .mcp.json
- Supprimer le cache
~/.cache/uv
- Signaler l’incident à l’équipe sécurité de PyPI (
security@pypi.org) et aux mainteneurs de LiteLLM
-
Résultat de la vérification du cluster Kubernetes
- Aucun pod malveillant (
node-setup-*, sysmon) n’a été trouvé
- L’exécution ayant eu lieu sur macOS, la propagation interne au cluster a échoué
- Toutefois, en raison de l’exposition possible de
~/.kube/config, une rotation des identifiants reste nécessaire
Réponse publique et actions côté PyPI
- À 11:58 UTC, le paquet litellm 1.82.8 a été téléchargé depuis PyPI dans un environnement Docker isolé, ce qui a permis de reconfirmer la présence du fichier
.pth malveillant
- Signalement immédiat à l’équipe sécurité de PyPI et au dépôt BerriAI/litellm
- L’incident a ensuite été enregistré sous PYSEC-2026-2 (CVE)
- À 12:01 UTC, publication et diffusion sur le blog FutureSearch d’un billet révélant l’attaque de la chaîne d’approvisionnement
- La PR a été rédigée et fusionnée en 3 minutes
- À 12:04 UTC, proposition de diffusion dans les communautés r/Python, r/netsec, r/LocalLLaMA, r/MachineLearning et r/devops
- Objectif : accélérer la réponse des communautés Python et sécurité
Signification de l’incident
- L’outil d’analyse de code basé sur l’IA Claude Code a identifié le comportement malveillant en temps réel et a généré une alerte avant l’intervention de chercheurs en sécurité
- Cet incident illustre une attaque de la chaîne d’approvisionnement visant directement l’écosystème des développeurs IA, et souligne la nécessité de renforcer la sécurité des comptes PyPI et la vérification des mises à jour automatiques
- Il montre aussi que les outils d’IA peuvent aller au-delà de l’assistance au développement pour être utilisés dans la détection et l’automatisation de la réponse aux cybermenaces
1 commentaires
Commentaires Hacker News
Je suis le développeur qui a découvert et signalé en premier la faille de litellm
J’ai partagé la transcription d’analyse en temps réel retraçant exactement ce qui s’est passé
Claude m’a guidé étape par étape sur les personnes à contacter et l’ordre dans lequel agir, ce qui a été très utile même pour quelqu’un qui n’est pas expert en sécurité
Je me demande si le fait que des non-spécialistes découvrent et signalent des vulnérabilités de cette manière aide la communauté sécurité ou, au contraire, crée de la confusion
En revanche, le passage disant que « le paquet malveillant s’est exécuté dès la réouverture de Cursor » semble assez risqué
Dès qu’un doute apparaissait, il aurait fallu isoler la machine et contacter l’équipe sécurité en priorité
Si le fichier .pth ne s’était pas comporté comme une fork bomb, cela aurait peut-être été détecté bien plus tard
Demander à Claude qui contacter était une bonne décision
Comme je ne connaissais pas les contacts liés à PyPI, j’ai envoyé un mail au mainteneur et j’ai aussi posté sur Hacker News
Même sans faire partie de la communauté sécurité, je pense que tout le monde devrait pouvoir signaler ce type de vulnérabilité critique
La plupart des problèmes viennent de gens qui veulent juste gagner de l’argent en prétendant que n’importe quoi est une faille
Mais ton signalement était de grande qualité, et ce genre de cas passe directement en priorité de correctif
Si le problème pouvait être résolu sans interrompre l’activité, on agissait immédiatement ; s’il était grave, on remontait directement au CISO ou au CTO
Grâce à ton signalement, un incident plus grave a été évité
Nous avons nous aussi récapitulé le sujet dans deux billets de blog
article de blog grith.ai
Mais ce cas me semble être un bon exemple de la manière dont l’IA a permis d’accélérer considérablement l’analyse de la cause et le signalement
C’est la première fois que je vois mon outil claude-code-transcripts intégré comme donnée dans un billet de blog
D’habitude, je le partageais via la page HTML de Gist, donc cet usage est intéressant
Nous avons essayé de l’adapter à notre style de blog sans succès, et cela m’a rappelé à quel point l’expérience de base est importante
Claude récupère les logs comme s’il scannait tout mon ordinateur, donc j’ai ressenti le besoin d’un système automatique d’édition des logs
C’est particulièrement pénible quand on collabore en équipe pendant un débogage urgent
Des demandes du type « peut-on afficher le contenu du script malveillant sans l’exécuter ? » sont risquées
Les agents LLM n’ont pas de notion de responsabilité, donc une commande lancée par erreur peut provoquer un gros incident
Quand on télécharge un fichier depuis PyPI, il faut impérativement le faire dans un environnement sandbox
Quand on me dit « ne fais pas ça », j’ai plutôt tendance à me focaliser dessus
J’ai entendu dire que PyPI prenait en charge les attestations numériques (digital attestation), donc je me demande si ce paquet était signé
documentation PyPI Trusted Publishers
Je pense que les registres de paquets comme GitHub, npm et PyPI devraient fournir un flux d’événements en temps réel (firehose) pour l’analyse de sécurité
Ce type d’attaque aurait pu être détecté immédiatement par un scanner automatique
Des partenaires sécurité scannent les paquets et peuvent faire des signalements via une API sur invitation
Voir le billet de blog de PyPI
article associé
L’objectif est de laisser aux scanners automatiques le temps de détecter des anomalies comme les fichiers .pth
Les dégâts économiques potentiels sont énormes, et rien que les personnes touchées par l’infection litellm sont plus de 47 000
La partie « rédaction du billet de blog, PR et merge en moins de 3 minutes » a été la plus choquante
C’est plus rapide que le temps de lecture, et cela donne un sentiment d’angoisse
Sans la fork bomb de 11 000 processus, cette attaque serait peut-être restée cachée bien plus longtemps
Si la bombe avait été ralentie, les dégâts auraient été bien plus importants
Pour une grande entreprise, il existe deux façons d’exécuter du code open source non fiable
En pratique, la méthode (1) est la plus sûre
Pour les PME ou les particuliers, le meilleur moyen de défense reste le pinning des dépendances assorti d’un délai d’attente suffisant
Avec Bazel, on peut se rapprocher de la méthode (1), mais la plupart des gens n’ont d’autre choix que de dépendre de sources externes
Le fait que PyPI ait isolé le paquet 30 minutes après le signalement montre une réponse vraiment rapide
L’un des meilleurs aspects de l’IA/LLM, c’est la démocratisation du reverse engineering
Avant, c’était une compétence difficile à apprendre et peu gratifiante, alors qu’aujourd’hui l’IA peut donner la direction
Le motif
exec(base64.b64decode(...))est souvent utilisé par les outils Python lorsqu’ils transmettent du code,mais, fondamentalement, tout code exécuté depuis /tmp, /var/tmp ou /dev/shm devrait être considéré comme très suspect
S’il y avait eu un outil de supervision réseau comme Lulu ou LittleSnitch, le trafic anormal aurait probablement été bloqué
En revanche, téléverser le binaire dans Claude pour lui faire analyser pose un autre risque