Ce qui s'est passé le 21 octobre 2026
Le 21 octobre 2026, un attaquant a compromis le pipeline de release de LiteLLM, un proxy Python open source qui unifie les appels à plusieurs fournisseurs d'IA (OpenAI, Anthropic, Azure, AWS Bedrock). Le package malveillant litellm==1.107.0 a été publié sur PyPI à 11 h 39 UTC et retiré à 13 h 23 UTC, soit environ deux heures d'exposition. Les images Docker officielles sur Docker Hub et GHCR (tags v1.107.0, latest, main-latest, main-stable) sont restées en ligne jusqu'à 14 h 20 UTC (source : LiteLLM).
Les administrateurs qui auto-hébergent LiteLLM sur un VPS ou un serveur dédié sont les premiers concernés : un simple pip install --upgrade litellm ou un docker pull pendant la fenêtre d'exposition suffisait à déployer le malware. Chez un hébergeur comme ElypseCloud, nous recommandons systématiquement d'épingler les versions des packages dans tout fichier de configuration Docker ou requirements.txt.
C'est la deuxième compromission de la chaîne d'approvisionnement de LiteLLM en sept mois. En mars 2026, les versions 1.82.7 et 1.82.8 avaient déjà été piégées pendant environ 40 minutes via une attaque ciblant la dépendance Trivy dans le pipeline CI/CD (source : LiteLLM). Cette récidive souligne le risque structurel lié aux dépendances tierces pour quiconque auto-héberge des services sur un VPS Linux ou un serveur dédié.
Comment le malware fonctionne
La version 1.107.0 embarquait trois scripts malveillants obfusqués, injectés dans chaque wheel Python et dans les images Docker. Le malware cible trois systèmes d'exploitation : Linux, macOS et Windows. Son mécanisme repose sur le système de hooks de démarrage de l'interpréteur Python.
| Fichier | Rôle |
|---|---|
cook.pth (12 octets) | Hook de démarrage Python : contient import cook. Le module site de Python exécute automatiquement les lignes import des fichiers .pth à chaque lancement de l'interpréteur, sans action de l'utilisateur. |
cook.py (22 251 caractères) | Voleur de credentials (nom interne : "privcollect"). Code obfusqué sur une seule ligne, exécuté dans un thread daemon pour rester invisible. Collecte les secrets puis les chiffre en AES-256-CBC avec enveloppe RSA-4096 avant exfiltration vers litellm.dev/healthcheck. |
sitecustomize.py (25 509 octets) | Daemon détaché (Linux et macOS uniquement) qui interroge un dépôt GitHub toutes les heures. Si le fichier domain.txt contient un nom d'hôte, le daemon télécharge et exécute du code arbitraire via exec(). |
Sous Windows, le daemon sitecustomize.py ne se détache pas en arrière-plan, mais le voleur cook.py s'exécute de la même façon à chaque lancement de Python depuis la ligne de commande, un script ou un service. Le fichier /tmp/remote_code_loader.lock sert de verrou pour empêcher les exécutions multiples du daemon. La variable d'environnement PRIVCOLLECT_ACTIVE=1 signale qu'un processus de vol est déjà en cours. Ces deux marqueurs sont aussi des indicateurs de compromission.
Quelles données sont dérobées
Le voleur de credentials cible 16 catégories de secrets sur le serveur compromis. Pour un administrateur de VPS ou de serveur dédié, voici les données les plus critiques :
- Clés SSH et GPG : le contenu du répertoire
~/.ssh/(clés privées,authorized_keys,known_hosts) et les clés GPG privées. Un attaquant en possession de vos clés SSH peut se connecter à tous les serveurs qui les acceptent. Consultez notre guide sécuriser SSH sur VPS Linux pour les bonnes pratiques de rotation. - Credentials cloud : identifiants AWS IAM, jetons Azure, clés de service GCP, tokens Kubernetes. Si votre VPS utilise un rôle IAM ou stocke des credentials cloud en variables d'environnement, ils sont exfiltrés.
- Mots de passe des navigateurs : bases de données de Chrome, Firefox, Edge et Brave (mots de passe, cookies, historique). Concerne les environnements de développement avec un navigateur installé, y compris les postes desktop.
- Tokens d'outils IA et CI/CD : tokens Claude, Cursor, GitHub Copilot, Gemini, ainsi que les credentials GitLab Runner, Jenkins et Vault.
- Mots de passe de bases de données : le malware parcourt les fichiers de configuration courants (
.env,config.php,settings.py) et extrait les chaînes de connexion MySQL, PostgreSQL et tout autre SGBD. Il exécute aussi des requêtes Prisma pour extraire les clés API (master keys et virtual keys) stockées dans la base de données du proxy LiteLLM. - Variables d'environnement : le malware lit les variables d'environnement de tous les processus en cours sur le serveur, pas seulement ceux de Python. Tout secret passé en variable d'environnement (tokens API, mots de passe, clés de chiffrement, credentials SMTP, URL de connexion
DATABASE_URL) est compromis.
Vérifier si votre serveur est touché
Connectez-vous en SSH à votre VPS ou serveur dédié. Les commandes suivantes en ligne de commande fonctionnent sur Ubuntu, Debian et la plupart des distributions Linux.
Vérifier la version du package LiteLLM
pip show litellm 2>/dev/null | grep VersionSi la sortie affiche Version: 1.107.0, votre installation est compromise. Toute autre version (notamment 1.106.2) n'est pas concernée.
Chercher les fichiers malveillants
Le malware dépose ses fichiers dans le répertoire site-packages de Python. Cherchez-les dans tous vos environnements virtuels et dans l'installation système :
sudo find / -type f \( -name "cook.pth" -o -name "cook.py" -o -name "sitecustomize.py" \) -path "*/site-packages/*" 2>/dev/nullVérifier le daemon de chargement de code distant
ls -la /tmp/remote_code_loader.lock 2>/dev/null
ls -la /tmp/.pc_once_* 2>/dev/nullSi l'un de ces fichiers existe, le malware a été exécuté sur votre serveur. Le fichier .pc_once_* est un marqueur d'exfiltration réussie : vos credentials ont déjà été envoyés à l'attaquant.
Vérifier les images Docker
Si vous utilisez LiteLLM via Docker sur votre VPS, vérifiez le tag de l'image en cours d'exécution :
docker inspect --format='{{.Config.Image}}' $(docker ps -q --filter ancestor=ghcr.io/berriai/litellm) 2>/dev/null
docker inspect --format='{{.Config.Image}}' $(docker ps -q --filter ancestor=litellm/litellm) 2>/dev/nullSi l'image porte le tag v1.107.0, latest, main-latest ou main-stable et a été tirée (pull) entre le 21 octobre 11 h 46 UTC et 14 h 20 UTC, elle contient le malware.
Consulter les logs du serveur
Si le malware a été exécuté, vérifiez les logs système pour détecter d'éventuelles connexions suspectes ou des mouvements latéraux. Depuis la ligne de commande :
sudo journalctl --since "2026-10-21" | grep -i "ssh.*accepted"
sudo grep "Accepted" /var/log/auth.log | tail -50Recherchez des connexions depuis des adresses IP inconnues. Si votre serveur héberge un serveur web (Nginx ou Apache), consultez aussi les logs d'accès pour repérer des requêtes inhabituelles. Auditez les scripts cron et les tâches planifiées pour vérifier qu'aucune porte dérobée n'a été ajoutée :
sudo crontab -l
sudo ls -la /etc/cron.d/
for user in $(cut -f1 -d: /etc/passwd); do echo "--- $user ---"; sudo crontab -u "$user" -l 2>/dev/null; donePour un audit plus poussé des processus et des connexions réseau, consultez nos guides auditer l'activité d'un serveur avec auditd et lister les ports en écoute avec ss.
Nettoyer un serveur compromis
Si vous avez détecté des fichiers malveillants, suivez cette procédure dans l'ordre. Utilisez un shell sh ou bash brut pour les premières étapes : tout lancement de Python réexécute le hook cook.pth.
1. Tuer le daemon
sudo lsof /tmp/remote_code_loader.lock 2>/dev/null | awk 'NR>1{print $2}' | xargs -r kill -9
rm -f /tmp/remote_code_loader.lock /tmp/.pc_once_*2. Supprimer les fichiers malveillants
sudo find / -type f \( -name "cook.pth" -o -name "cook.py" \) -path "*/site-packages/*" -delete 2>/dev/nullPour sitecustomize.py, vérifiez qu'il s'agit bien de la version malveillante (25 509 octets) avant de le supprimer, car certains projets utilisent légitimement ce fichier :
sudo find / -type f -name "sitecustomize.py" -path "*/site-packages/*" -size +20k -delete 2>/dev/null3. Reconstruire les environnements Python
Ne vous contentez pas de réinstaller le package par-dessus : recréez vos environnements virtuels depuis zéro. Cette migration vers la version saine élimine tout résidu des scripts malveillants dans le répertoire site-packages :
rm -rf /chemin/vers/venv
python3 -m venv /chemin/vers/venv
source /chemin/vers/venv/bin/activate
pip install litellm==1.106.24. Redémarrer les services
Après le nettoyage, redémarrez tous les services qui utilisent Python pour vous assurer qu'aucun processus ne tourne encore avec le code compromis en mémoire :
sudo systemctl restart litellm
sudo systemctl restart votre-service-pythonVérifiez qu'aucun processus Python suspect ne persiste :
ps aux | grep python5. Rotation de tous les secrets
Partez du principe que tout secret accessible depuis le serveur est compromis. Renouvelez dans cet ordre :
- Clés SSH : générez de nouvelles paires et configurez les fichiers
authorized_keyssur chaque serveur distant (configurer une clé SSH sur VPS Linux) ; - Tokens API (OpenAI, Anthropic, AWS, GCP, Azure) ;
- Mots de passe des bases de données MySQL et PostgreSQL ;
- Clés API LiteLLM (master key et virtual keys) ;
- Tokens CI/CD (GitLab, Jenkins, GitHub).
Pensez aussi à vérifier vos sauvegardes (backup) : si une sauvegarde automatique a capturé l'état compromis, ne la restaurez pas telle quelle. Pour configurer la rotation automatique de vos mises à jour de sécurité, consultez notre guide automatiser les mises à jour de sécurité sur VPS Ubuntu.
Bonnes pratiques Docker pour auto-hébergeurs
Cet incident illustre pourquoi les tags :latest et les mises à jour automatiques de dépendances sont dangereux en production sur un VPS ou un serveur dédié. Que votre serveur tourne sur un VPS en virtualisation KVM, une machine virtuelle ou un serveur physique dédié, les mêmes règles s'appliquent à tout conteneur Docker :
- Épinglez les versions : dans votre
Dockerfileet votre fichier de configurationdocker-compose.yml, spécifiez toujours un tag de version précis (litellm/litellm:v1.106.2) au lieu de:latest. Undocker pullsur:latestaurait tiré la version piégée pendant la fenêtre d'exposition. Consultez notre guide Docker Compose sur VPS Linux pour configurer vos services correctement. - Vérifiez les digests : pour les services critiques, épinglez le hash SHA256 de l'image plutôt que le tag. Un tag peut être réécrit par un attaquant, mais pas le digest :
litellm/litellm@sha256:abc123... - Ne tirez pas en production automatiquement : désactivez les outils comme Watchtower ou les cron jobs de
docker-compose pull && docker-compose up -dsur vos serveurs de production. Testez chaque nouvelle version sur un environnement isolé avant de la déployer. - Isolez les conteneurs : ne montez pas le socket Docker (
/var/run/docker.sock) dans un conteneur qui n'en a pas besoin. Ne lancez pas les conteneurs en mode--privileged. Utilisez un utilisateur non-root dans vos images. Installer Docker sur un VPS détaille les configurations initiales sécurisées. - Monitoring des conteneurs : un conteneur compromis peut consommer des ressources anormales en processeur, RAM ou bande passante réseau sortante. Surveillez les ressources de votre VPS avec htop et btop pour repérer les anomalies. Auditez régulièrement les processus en cours avec
docker topet les connexions réseau avecss -tlnp.
Ces principes s'appliquent à tout service conteneurisé : proxy IA, panel Pterodactyl, serveur de jeu, base de données. Un seul conteneur tirant un tag compromis suffit à exposer l'ensemble des secrets du serveur.
FiveM
Minecraft
Rust
RedM
Hytale