LiteLLM a été détourné : auditez votre chaîne d'outils d'IA cette semaine
TeamPCP a expédié des logiciels malveillants de vol d'informations d'identification dans une version LiteLLM et a vidé les clés AWS, GCP et SSH des machines de développement. Cinq vérifications à exécuter avant votre prochaine installation de pip.
En mars 2026, un acteur malveillant se faisant appeler TeamPCP a publié une version falsifiée de
litellm, la bibliothèque Python qui regroupe plus de 100 fournisseurs LLM derrière un seul
Interface compatible OpenAI. La version a livré un infostealer connecté au chemin de post-installation.
Quiconque a couru pip install litellm pendant la fenêtre remise des clés privées SSH,
Informations d'identification AWS, jetons Azure, JSON du compte de service GCP et Docker config.json
fichiers vers un point de terminaison contrôlé par un attaquant. The Hacker News, Ardan Labs et Security Boulevard
chacun a confirmé l'attribution et la liste des artefacts exfiltrés.
LiteLLM n’est pas obscur. Il se trouve à l'intérieur des cadres d'agents, à l'intérieur des pipelines CI qui acheminent l'évaluation trafic entre les fournisseurs, dans les blocs-notes Jupyter sur l'ordinateur portable d'un data scientist qui contiennent également informations d'identification cloud de longue durée. Une seule version compromise a donné à l'attaquant un portefeuille de fournisseur clés, un ensemble de rôles cloud et le matériel SSH pour déplacer latéralement dans chaque dépôt ces clés pourrait atteindre.
Vous ne pouvez pas empêcher le vol du jeton PyPI d'un responsable. Vous pouvez réduire votre rayon d'explosion de sorte que lorsque la prochaine bibliothèque d'IA sera touchée ; et ce sera le cas ; un ordinateur portable ne se transforme pas en un incident cross-cloud. Voici cinq contrôles qui valent la peine d’être effectués cette semaine dans l’ensemble de l’IA chaîne d'outils : LiteLLM, LangChain, LlamaIndex, wrappers Ollama, SDK Claude, clients MCP et tous cadre d'agent que vous avez en production.
Ce que TeamPCP a réellement pris
La charge utile a couru à l'intérieur setup.py et un crochet de post-installation. Lors de l'importation ou de l'installation
lisez ce qui suit dans le répertoire personnel du développeur et dans le système de fichiers CI Runner :
~/.ssh/id_rsa,id_ed25519, etknown_hosts~/.aws/credentialset~/.aws/configprofils~/.azure/jetons et actualiser les informations d'identification- GCP
application_default_credentials.jsonet fichiers JSON du compte de service ~/.docker/config.jsony compris les jetons d'authentification du registre- Variables d'environnement commençant par
AWS_,GCP_,OPENAI_,ANTHROPIC_,GITHUB_
Le canal exfil était un simple HTTPS POST vers un domaine attaquant qui tournait chaque semaine. Retrait s'est produit en quelques jours, mais cette fenêtre était suffisante ; les informations d’identification qui ont été divulguées ne peuvent pas être divulguées. Passons aux contrôles.
Contrôle 1 : épingler les versions exactes, pas les plages
La ^1.14.0 et ~=1.48 modèles dans requirements.txt,
pyproject.toml, et package.json laisser toute nouvelle version mineure ou patch
rouler dans un environnement propre pendant la nuit. C'est ainsi qu'une fenêtre malveillante de trois heures devient un
exposition d'un mois; votre fichier de verrouillage n'a jamais été régénéré mais votre cache CI a supprimé le mauvais
version sur sa prochaine version à froid.
Épinglez les versions exactes. Épinglez par hachage lorsque l’écosystème le prend en charge.
Avec --require-hashes, pip refuse d'installer tout ce dont le SHA-256 ne correspond pas
ce que vous avez généré au moment du verrouillage. Une version compromise avec la même chaîne de version mais un
un hachage tarball différent échoue à l'installation. Paire pip-compile --generate-hashes avec un
Travail CI qui régénère le fichier de hachage uniquement lors de mises à jour de dépendances explicites, jamais de manière simple
installer.
Les utilisateurs de poésie bénéficient du même filet de sécurité via le fichier de verrouillage. Le piège est la syntaxe du caret dans
pyproject.toml; remplacez-le par des broches exactes :
poetry install --sync supprime tout package qui n'est pas dans le fichier de verrouillage, ce qui arrête
une dépendance parasite qui se cache entre les déploiements. Pour les outils d'IA côté npm, utilisez
npm ci (pas npm install) à chaque exécution et validation de CI
package-lock.json.
Contrôle 2 : isoler les informations d'identification des shells de développement
Un shell de développement qui a ~/.aws/credentials avec une clé d'accès de longue durée est un chargé
pistolet pointé sur votre facture cloud et vos données clients. LiteLLM n'avait pas besoin de ces informations d'identification pour
faire son travail ; ils sont restés sur le disque parce que le développeur a déjà exécuté aws configure et
jamais nettoyé.
Déplacez les informations d'identification du disque. Chargez-les à la demande, limitez-les et révoquez le persistant. couche :
-
AWS :
aws sso loginavec une durée de session plafonnée à 8h00 à 12h00 heures. Supprimer~/.aws/credentials. Tout devrait passer par~/.aws/ssocache qui expire tout seul. -
GCP :
gcloud auth application-default loginavec--lifetime=43200. Révoquez les JSON de compte de service de longue durée installés sur les ordinateurs portables ; utilisez la fédération d’identité de charge de travail de CI. -
Azurée:
az loginavec un accès conditionnel qui force l’AMF ; tuer jetons d’actualisation stockés datant de plus de 12 heures. -
Clés API : conservez-les dans 1Password, Vault ou Doppler. Injecter au début du processus
via
op runouvault read. Ne les exportez jamais dans~/.zshrc.
Si TeamPCP n'avait trouvé que des jetons de session STS expirés, le rayon d'explosion s'arrêterait au bout de quelques heures d'accès. L'incident s'est produit parce que des clés de longue durée se trouvaient en clair sur le disque, prêtes à être utilisées. lire.
Contrôle 3 : analysez chaque installation avec un bac à sable
Avant de faire confiance à une nouvelle bibliothèque d'IA ou à une mise à niveau d'une bibliothèque existante, installez-la quelque part ne peut pas accéder à vos informations d'identification. Un conteneur Docker jetable avec des capacités abandonnées et l'isolation du réseau vous indique si le code d'installation fait quelque chose de suspect :
Le modèle en deux étapes est important. La première étape nécessite un accès au réseau pour atteindre PyPI, donc une post-installation
le script pourrait encore s'exfiltrer. Exécutez la première étape sur une VM propre sans secrets et avec une règle de sortie DNS
qui enregistre chaque nom d'hôte sortant. La deuxième étape s'exécute avec --network=none; si votre
la bibliothèque essaie de téléphoner à la maison au moment de l'importation, l'importation échoue et vous savez.
Mieux : utilisez une microVM jetable comme Firecracker ou orb sur macOS pour la même chose
forme sans le noyau partagé de Docker. Pour JavaScript, le modèle d'autorisation de Deno vous donne le
même isolement sans conteneur : deno run --allow-net=api.openai.com,api.anthropic.com
agent.ts.
Contrôle 4 : vérifier l'exposition aux brèches avant la rotation
Si vos clés se trouvaient sur une machine qui a touché une mauvaise version, faites-les pivoter. Pas de débat. Mais aussi vérifiez si les identités liées à ces clés apparaissent déjà dans les dumps connus ; un ordinateur portable qui a exécuté une version LiteLLM compromise le mois dernier. Il se peut qu'il s'agisse d'un ordinateur portable dont le propriétaire a réutilisé les mots de passe. à partir d’un dump Collection1 2019. Les deux problèmes doivent être résolus et le contrôle 4 vous indique quels comptes nécessitent l’attention la plus urgente.
Botoi's /v1/breach/check le point de terminaison encapsule les mêmes sources de données que la plupart des IAM d'entreprise
les outils sont payants par siège et cela ne coûte rien sur le niveau gratuit :
Parcourez chaque e-mail de compte de service, chaque e-mail d'utilisateur de machine et chaque développeur humain dont l'ordinateur portable
touché la fenêtre. Tout e-mail avec password_exposed: true a besoin d'une rotation et d'un
Réinitialisation forcée du MFA avant de continuer. Transférez la sortie dans votre runbook de réponse aux incidents ; un
curl par identité, dix minutes pour une organisation d'ingénierie de 50 personnes.
Contrôle 5 : surveillez votre sortie sortante
Les logiciels malveillants post-installation doivent téléphoner à la maison d'une manière ou d'une autre. La plupart des développeurs ne se souviennent pas de la dernière fois ils ont regardé à quoi leur ordinateur portable parlait réellement ; c’est l’écart sur lequel TeamPCP comptait.
Sur une machine suspecte, une seule commande vous indique ce qu'est chaque processus Python et Node connecté à:
Au niveau de la flotte, faites passer chaque ordinateur portable de développeur et exécuteur CI via une sortie Zero Trust. liste verte. Cloudflare WARP, Tailscale ACL et Little Snitch vous donnent tous la même forme : listez les noms d'hôtes dont vous avez réellement besoin, bloquez le reste, alertez sur les blocages.
Une liste blanche aussi serrée semble dure la première semaine. Au cours de la deuxième semaine, les seules alertes que vous voyez sont réel : une bibliothèque essayant d’atteindre une destination qu’elle n’a pas à atteindre. C'est exactement le signal que le voleur d'informations de TeamPCP se serait déclenché lors de l'installation.
Les cinq contrôles en un coup d'œil
| Vérifier | Effort | Réduction du rayon de souffle |
|---|---|---|
| Épingler les versions exactes avec des hachages | 1 heure pour un seul repo ; 1 jour pour un monorepo | Arrête le déploiement silencieux d'une version compromise |
| Déplacer les informations d'identification vers des sessions de courte durée | 2 à 4 heures par développeur, une fois | Limite l'exfil à 8 à 12 heures d'accès au lieu de mois |
| Sandbox à chaque installation | 15 minutes par nouvelle évaluation de bibliothèque | Le code au moment de l'installation ne peut pas voir les vrais secrets ou le réseau de production |
| Identités de vérification des violations liées aux clés exposées | 10 minutes pour une organisation de 50 personnes | Donne la priorité aux rotations et aux réinitialisations MFA en fonction de l'exposition connue |
| Appliquer la liste d'autorisation de sortie sur les développeurs et CI | 1 jour pour configurer, continu pour maintenir | Bloque les canaux téléphoniques qui exfiltrent les données volées |
Points clés à retenir
- Épinglez les versions exactes, pas les plages. Un caret ou un tilde dans votre fichier de verrouillage est une promesse que la sortie de demain est sûre. TeamPCP a rompu cette promesse.
- Les informations d'identification cloud n'appartiennent pas aux shells de développement. Les sessions SSO de courte durée se transforment en informations d'identification volées dans un événement de rotation, pas une violation.
-
Sandbox s'installe avant de leur faire confiance. Docker avec majuscules et
--network=noneest suffisant pour détecter les logiciels malveillants au moment de l’installation pour le coût de 15 minutes. -
Rotation et vérification des violations. Si une machine a touché une mauvaise version, faites-la pivoter tous les
identité qu'il a vue et parcouru chaque e-mail
/v1/breach/checkpour trouver ceux qui besoin de réinitialisations MFA urgentes. - Les listes autorisées de sortie capturent le téléphone à la maison. Les règles Zero Trust sur les ordinateurs portables et CI deviennent un exfiltration silencieuse en un événement bruyant, enregistré et bloquable.
Botoi vous donne des points de terminaison HTTP pour la vérification des violations, la vérification du hachage, l'inspection SSL, HTTP audit d'en-tête et recherche de métadonnées npm ; les primitives dont vous avez besoin pour auditer une chaîne d'approvisionnement incident sans installer encore une autre bibliothèque. Une clé API, 5 req/min sur l'offre gratuite, non installer des crochets. Parcourez le documents interactifs ou câblez le Serveur MCP dans Claude Code ou Cursor pour appeler les mêmes points de terminaison depuis votre éditeur pendant que vous travaillez sur le liste de contrôle.
FAQ
- Quelles versions de LiteLLM ont été affectées et comment puis-je confirmer que je suis propre ?
- Les versions malveillantes ont fait surface en mars 2026 et sont restées sur PyPI suffisamment longtemps pour atterrir dans les caches CI et les ordinateurs portables des développeurs du monde entier. Exécutez pip show litellm pour imprimer votre version installée, puis faites une référence croisée à la version et téléchargez l'horodatage par rapport à l'avis de sécurité LiteLLM et à l'historique des versions de PyPI. Si une machine a exécuté pip install litellm pendant la fenêtre, traitez-la comme compromise : faites pivoter chaque clé cloud qui se trouvait dans ce shell, redéployez à partir d'une image propre et effacez les jetons ~/.aws, ~/.config/gcloud et ~/.ssh antérieurs à la rotation.
- Était-ce une erreur PyPI ou une erreur LiteLLM ?
- Les deux, et c’est la leçon. LiteLLM est une bibliothèque légitime avec un véritable responsable ; l'attaquant a utilisé un canal de publication compromis, pas un typosquat. PyPI ne nécessite toujours pas de versions signées ni de 2FA obligatoire sur les jetons pour chaque projet, de sorte qu'un identifiant de téléchargement volé se transforme en malware expédié en quelques minutes. La signature du paquet via Sigstore et les jetons à l'échelle du responsable auraient interrompu l'attaque lors du téléchargement.
- Dois-je alterner chaque clé AWS ou uniquement celles utilisées sur les machines concernées ?
- Faites-les tous pivoter. Les attaquants passent par STS, assument les chaînes de rôles et les politiques de confiance entre comptes dès qu’ils disposent d’une seule clé à longue durée de vie. Si l'ordinateur portable ou le programme d'exécution CI qui a vu la mauvaise version avait des informations d'identification IAM en mémoire ou sur le disque, traitez l'intégralité du graphique principal accessible à partir de cette identité comme chaud. Même logique pour les comptes de service GCP et les principaux de service Azure.
- Bun ou Deno changent-ils cela pour les outils JavaScript AI ?
- Un peu, pas beaucoup. Deno exécute du code avec des autorisations explicites (--allow-net, --allow-env), donc une bibliothèque qui tente soudainement de lire ~/.aws/credentials est refusée à moins que vous n'ayez accordé l'accès au système de fichiers. Bun a un indicateur --frozen-lockfile et n'exécute pas de scripts d'installation par défaut dans les versions récentes. Les deux constituent des améliorations par rapport aux valeurs par défaut de NPM, mais aucune n'empêche une bibliothèque d'exfiltrer des données une fois que le code de votre application lui remet les informations d'identification au moment de l'exécution.
- Qu’est-ce qui différencie le risque de chaîne d’approvisionnement de la chaîne d’outils IA du risque NPM ou PyPI habituel ?
- Les bibliothèques d’IA sont inhabituellement proches des secrets. Un wrapper LLM comme LiteLLM a besoin de clés API pour plus de 10 fournisseurs dans un fichier env. Un agent LangChain lit les informations d'identification AWS afin de pouvoir appeler S3 comme outil. Un SDK Claude touche GITHUB_TOKEN car vous lui avez demandé d'ouvrir des PR. Le rayon d'explosion par installation est supérieur à celui d'une bibliothèque d'utilitaires typique ; une version compromise vous offre un portefeuille de clés de fournisseur, des informations d'identification cloud et un accès au code source en une seule fois.
Commencez a construire avec botoi
150+ endpoints API pour la recherche, le traitement de texte, la generation d'images et les utilitaires pour developpeurs. Offre gratuite, sans carte bancaire.