Mémo interne • 25 mars 2026
Analyse post-incident — Supply Chain

Risques de chaîne d’approvisionnement : le cas de LiteLLM compromis

Le 24 mars 2026, deux versions malicieuses du package Python litellm ont été publiées sur PyPI. Ce mémo décortique la mécanique de l'attaque, les patterns utilisés par le groupe TeamPCP, et les leçons concrètes pour protéger nos pipelines.

Audience : Toute l'équipe
~3h
Fenêtre d'exposition sur PyPI
3.4M
Téléchargements / jour (litellm)
3
Étapes du payload malicieux
11+
Projets open source touchés
9e
Opération connue de TeamPCP


Qu'est-ce que LiteLLM et pourquoi c'est important?

LiteLLM est une librairie Python très populaire qui sert de passerelle unifiée vers plusieurs fournisseurs de modèles de langage (OpenAI, Anthropic, Azure, etc.). Beaucoup d'équipes l'utilisent comme proxy centralisé pour gérer leurs clés API et router les requêtes vers différents LLM.

Pourquoi c'est pertinent pour nous

Si on utilise des outils d'IA qui dépendent de LiteLLM (directement ou via des sous-dépendances), ou si nos pipelines CI/CD utilisent des librairies/outils sans versions épinglées, ce type d'attaque nous concerne directement.



La chaîne d'attaque en un coup d'oeil

Ce qui rend cette attaque redoutable, c'est l'enchaînement. L'attaquant n'a pas ciblé LiteLLM directement. Il a compromis un outil de sécurité utilisé par LiteLLM dans son processus de build.

1. Trivy compromis
Scanner de sécurité piégé via une faille CI/CD
2. Token volé
Le pipeline de LiteLLM exécute le Trivy piégé, qui vole le token PyPI
3. Package empoisonné
Publication de versions malicieuses avec le token volé
4. Payload à 3 étapes
Collecte, exfiltration chiffrée, backdoor persistante

Les versions malicieuses passent toutes les vérifications d'intégrité standard (hashes, signatures) parce qu'elles ont été publiées avec les vrais identifiants du mainteneur. Pas de typosquatting, pas de modification après publication. C'est le compte officiel qui publie.



Comment l'attaque s'est déroulée

L'attaque contre LiteLLM n'est pas un événement isolé. C'est la 9e phase d'une campagne menée par le groupe TeamPCP. Tout a commencé cinq jours avant avec la compromission d'un autre outil.

Fin février 2026
TeamPCP exploite une faille dans le pipeline CI de Trivy (un scanner de sécurité open source d'Aqua Security) et vole les identifiants d'un bot maintenant le projet.
19 mars — 17h43 UTC — Trivy compromis
Les tags Git de l'action GitHub de Trivy sont réécrits pour pointer vers une version malicieuse (v0.69.4). Tout pipeline CI qui utilise Trivy sans épingler une version précise récupère cette version piégée.
23 mars — Domaine enregistré
Les attaquants enregistrent le domaine models.litellm.cloud (qui ressemble au domaine légitime litellm.ai) pour y recevoir les données volées. Checkmarx KICS est aussi compromis dans la même opération.
24 mars, 10h39 UTC — Publication v1.82.7
Le pipeline CI/CD de LiteLLM exécute Trivy (version non épinglée). La version piégée extrait le token de publication PyPI. Avec ce token, les attaquants publient litellm 1.82.7.
24 mars, 10h52 UTC — Publication v1.82.8
Treize minutes plus tard, litellm 1.82.8 est publiée avec un mécanisme encore plus agressif : un fichier .pth qui s'exécute automatiquement au démarrage de Python.
24 mars, 11h48 UTC — Découverte
Un développeur (Callum McMahon, FutureSearch) remarque que sa machine manque de RAM juste après avoir installé litellm. Il trace le problème jusqu'à un fichier .pth suspect, encodé en double base64.
24 mars, 12h44 UTC — Suppression de l'alerte
Les attaquants utilisent le compte GitHub compromis pour fermer le ticket et inondent les commentaires avec 88 bots (73 comptes différents) en 102 secondes pour noyer l'alerte.
24 mars, ~13h38 UTC — Quarantaine PyPI
PyPI met le package en quarantaine. Les versions malicieuses sont retirées. Fenêtre d'exposition totale : ~3 heures.
24 mars, 15h09 UTC — Rotation des secrets
Le mainteneur confirme la rotation complète de toutes les clés (GitHub, Docker, PyPI).


Deux versions, deux techniques différentes

Les attaquants ont publié deux versions coup sur coup, chacune avec une technique d'injection différente. La deuxième était plus agressive.

Version 1.82.7

Injection dans le code source

Le code malicieux était caché (encodé en base64) directement dans le fichier principal du serveur proxy. Il s'exécutait quand quelqu'un importait le module proxy de LiteLLM — un import très courant.

Version 1.82.8

Fichier .pth (plus dangereux)

Un fichier .pth a été ajouté au package. Ce type de fichier est exécuté automatiquement à chaque démarrage de Python — même quand on lance pip install, un IDE, ou n'importe quel script. Aucun import nécessaire.

Pourquoi le fichier .pth est si vicieux

Il s'exécute à chaque fois que Python démarre. Le simple fait d'installer un autre package avec pip pouvait déclencher le payload. C'est aussi ce mécanisme qui a trahi l'attaque : le fichier lançait un sous-processus Python qui lui-même déclenchait le .pth, créant une boucle infinie qui a fait exploser la RAM de la machine du découvreur.



Que faisait le code malicieux (en 3 étapes)

Le code malicieux fonctionne en trois étapes, toutes automatiques, sans interaction requise.

Étape 1

Collecte massive de secrets

Le script ratissait la machine à la recherche de tout ce qui a de la valeur :

  • Clés SSH, fichiers .env, historique Git
  • Identifiants AWS, GCP et Azure (incluant les métadonnées d'instance)
  • Tokens Kubernetes et secrets Docker
  • Tokens Slack/Discord, configs Jenkins/Terraform
  • Wallets de cryptomonnaie (Bitcoin, Ethereum, etc.)
Étape 2

Chiffrement et exfiltration

Les données volées étaient chiffrées avec AES-256, puis la clé de session était elle-même chiffrée avec une clé RSA 4096 bits codée en dur. Le tout était envoyé vers models.litellm.cloud.

Même si quelqu'un interceptait le trafic réseau, impossible de lire les données sans la clé privée de l'attaquant.

Étape 3

Backdoor persistante + propagation

Le script installait un service système déguisé en « System Telemetry Service » qui contactait un serveur de commande toutes les 5 minutes pour recevoir des instructions.

Sur Kubernetes, il tentait de lire tous les secrets de tous les namespaces puis de déployer des pods malicieux sur chaque noeud du cluster.



Pourquoi les contrôles habituels n'ont rien vu

Vérification de hash (pip)

Le hash vérifie que le fichier téléchargé correspond à ce que PyPI annonce. Ici, PyPI annonçait le fichier malveillant. Le hash matche donc parfaitement. Aucune alerte.

Identifiants légitimes

Les versions ont été publiées avec le vrai token du mainteneur. Pas de typosquatting, pas de compte suspect. C'est le « vrai » package, publié par le « vrai » compte.

Signature du wheel

Le fichier .pth malveillant est correctement déclaré dans le RECORD du wheel. L'intégrité interne du package est valide. Il faudrait inspecter le contenu du .pth pour détecter le problème.

Suppression du signalement

Les attaquants ont utilisé le compte compromis pour fermer l'issue GitHub de signalement et ont déployé 88 commentaires de bots en 102 secondes pour noyer l'alerte légitime.



Qui a été touché?

En seulement 3 heures, plusieurs projets open source majeurs dans l'écosystème IA ont été affectés et ont dû réagir en urgence le même jour.

ProjetAction prise
DSPy (Stanford NLP)PR fusionné pour épingler la version; échec CI rapporté
MLflowPR fusionné pour bloquer les versions compromises
OpenHandsPR de correction soumis
CrewAIDécouplé de litellm; deux PR de mitigation
Arize PhoenixPR de correction soumis
AiderConfirmé non affecté (version épinglée à 1.82.3)

Le mécanisme .pth est particulièrement dangereux dans les environnements CI/CD. Le code malicieux s'exécute pendant les étapes de build, pas seulement au démarrage de l'application. Chaque pipeline qui a installé litellm pendant cette fenêtre de 3 heures est potentiellement compromis.



Comment l'attaquant a tenté d'étouffer l'alerte

Quand la communauté a commencé à signaler le problème sur GitHub, les attaquants n'ont pas simplement ignoré les alertes. Ils ont utilisé le compte GitHub compromis du mainteneur pour fermer le ticket en le marquant « not planned », puis ont inondé les commentaires avec 88 messages de bots en 102 secondes pour noyer toute discussion légitime.

C'est un rappel que dans une attaque supply chain, l'attaquant contrôle souvent les canaux de communication officiels du projet compromis. La communauté a contourné le problème en ouvrant un nouveau ticket et en discutant sur Hacker News.



Ce que ça nous apprend sur la sécurité de la supply chain

01

Épinglez tout. Vraiment tout.

Pas juste les dépendances applicatives. Les GitHub Actions, les outils de CI, les scanners de sécurité. Si un outil est tiré sans version fixe, on lui donne accès à nos secrets sans garantie sur ce qu'il contient.

02

Vos outils de sécurité sont aussi des cibles

TeamPCP cible spécifiquement les outils de sécurité (Trivy, Checkmarx KICS) parce qu'ils ont des accès privilégiés par nature. Un scanner de vulnérabilités a besoin de lire le code, les configs, les secrets. Si l'outil est compromis, l'attaquant hérite de ces permissions.

03

Moindre privilège dans les pipelines

Limiter les tokens disponibles dans chaque étape du CI/CD. Le token PyPI n'a pas besoin d'être accessible pendant l'étape de scan de sécurité. Séparer les permissions réduit le rayon d'explosion.

04

Intégrité du package ≠ sécurité du package

Un hash valide confirme qu'on a reçu exactement ce qui a été publié. Ça ne dit rien sur la fiabilité de ce qui a été publié. Il faut des contrôles complémentaires : analyse statique du contenu, surveillance des patterns suspects.

05

Surveiller les dépendances transitives

LiteLLM est une sous-dépendance de dizaines de frameworks IA. On peut être affecté sans l'avoir installé directement. Un audit régulier de l'arbre complet de dépendances est essentiel.

06

Les signalements peuvent être étouffés

L'attaquant a fermé le ticket GitHub et noyé la discussion avec des bots. Il faut des canaux de signalement alternatifs et une culture d'entreprise où une alerte sécurité ne dépend pas d'un seul canal.



Que faire maintenant?

1

Vérifier si litellm est dans vos projets

Lancez pip show litellm | grep Version dans tous vos environnements. Si vous voyez 1.82.7 ou 1.82.8, traitez le système comme compromis.

2

Épingler à une version sûre

Si vous utilisez litellm, épinglez à <=1.82.6 dans vos requirements jusqu'à la publication d'une version propre confirmée.

3

Auditer vos pipelines CI/CD

Vérifiez que chaque outil installé dans vos workflows est épinglé à une version précise ou un hash de commit. Les GitHub Actions, les outils apt, les packages pip — tout.

4

Si compromis : rotation complète des secrets

Si la version malicieuse a été installée, considérez que toutes les clés SSH, tokens API, credentials cloud, secrets Kubernetes et fichiers .env de cette machine sont compromis. Rotation complète requise.

5

Chercher les artéfacts de persistance

Vérifiez la présence de ~/.config/sysmon/sysmon.py et du service systemd sysmon.service. Sur Kubernetes, cherchez des pods nommés node-setup-* dans le namespace kube-system.



Le pattern plus large : un groupe organisé

TeamPCP n'est pas un acteur opportuniste. Le groupe est actif depuis au moins décembre 2025 et cette attaque est leur 9e opération connue. Ils ciblent systématiquement des outils ayant des accès élevés aux pipelines automatisés.

ÉlémentDétail
GroupeTeamPCP (actif depuis décembre 2025)
StratégieCompromettre les outils de CI/CD → voler les secrets de publication → empoisonner des packages populaires
CiblesTrivy (scanner de conteneurs), Checkmarx KICS (scanner IaC), LiteLLM (routeur LLM)
Point communDes outils avec des accès élevés, utilisés massivement en mode automatisé
PayloadCollecte de tous les secrets → chiffrement → exfiltration → persistance + propagation Kubernetes
Exfiltrationmodels.litellm.cloud (enregistré la veille de l'attaque)
InnovationUtilisation de l'Internet Computer Protocol (ICP) comme canal de commande indémontable, et d'un agent IA pour le ciblage automatisé
AttributionMême clé RSA publique retrouvée dans les payloads des trois opérations

Le message clé : Ce n'est pas un incident isolé. C'est un pattern récurrent qui va s'accélérer. La supply chain logicielle, en particulier autour de l'écosystème IA/ML, est une surface d'attaque croissante. Nos pratiques doivent évoluer en conséquence.



Pour aller plus loin

Analyse complète de l'attaque

L'article de recherche contient les hashes des fichiers malicieux, les indicateurs de compromission réseau, et les commandes de détection détaillées.

snyk.io/articles/poisoned-security-scanner-backdooring-litellm ↗