Aller au contenu
Guide

LiteLLM a été détourné : auditez votre chaîne d'outils d'IA cette semaine

| 8 min read

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.

Server rack representing supply chain infrastructure and credential exposure
Photo by Taylor Vick on Unsplash

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, et known_hosts
  • ~/.aws/credentials et ~/.aws/config profils
  • ~/.azure/ jetons et actualiser les informations d'identification
  • GCP application_default_credentials.json et fichiers JSON du compte de service
  • ~/.docker/config.json y 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 login avec une durée de session plafonnée à 8h00 à 12h00 heures. Supprimer ~/.aws/credentials. Tout devrait passer par ~/.aws/sso cache qui expire tout seul.
  • GCP : gcloud auth application-default login avec --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 login avec 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 run ou vault 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=none est 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/check pour 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.