Détournement du package npm Bitwarden CLI : découverte d’une vaste attaque de vol d’identifiants de développeurs
(research.jfrog.com)L’équipe de recherche en sécurité de JFrog a découvert que la version 2026.4.0 de @bitwarden/cli sur npm avait été détournée. Tout en conservant intactes les métadonnées et le branding légitimes de Bitwarden, seuls le script preinstall et le point d’entrée du binaire bw ont été remplacés par un chargeur malveillant (bw_setup.js).
Mode opératoire
Lors de l’installation, le chargeur télécharge d’abord le runtime Bun depuis GitHub, puis exécute une charge utile JavaScript obfusquée (bw1.js). Le simple fait d’utiliser Bun au lieu de Node.js constitue déjà une stratégie d’évasion de la détection.
La charge utile collecte à grande échelle des identifiants présents sur les postes de travail des développeurs et dans les environnements CI via trois collecteurs.
- Collecteur de système de fichiers : clés SSH (
~/.ssh/), identifiants Git (.git-credentials), tokens npm (~/.npmrc),.env, identifiants AWS (~/.aws/credentials), credentials GCP (~/.config/gcloud/credentials.db), etc. - Collecteur shell/environnement : exécution de la commande
gh auth token, analyse deprocess.envpour repérer les motifs de tokens GitHub et npm - Collecteur GitHub Actions : injection de workflows dans les dépôts où le token dispose des autorisations, afin d’extraire aussi les secrets Actions
Point particulièrement notable : les fichiers de configuration d’outils IA et MCP comme ~/.claude.json, ~/.claude/mcp.json, ~/.kiro/settings/mcp.json font également partie des données visées.
Double voie d’exfiltration
Les données dérobées sont compressées avec gzip, puis transmises après chiffrement hybride AES-256-GCM + RSA-OAEP.
- Voie principale : requête HTTPS POST vers
audit.checkmarx.cx/v1/telemetry(camouflée en service de sécurité légitime) - Voie secondaire (abus de GitHub) : en cas d’échec de la première voie, le malware recherche dans les messages de commit GitHub un PAT encodé deux fois en Base64 à l’aide du marqueur
LongLiveTheResistanceAgainstMachines, puis l’extrait. À l’aide du marqueurbeautifulcastleet d’une vérification de signature RSA, il reconstitue aussi dynamiquement un domaine alternatif d’exfiltration. Il crée finalement un nouveau dépôt dans le compte GitHub de la victime et y téléverse un JSON chiffré dans le répertoireresults/.
Détection de l’infection
Les métadonnées intégrées du Bitwarden CLI légitime indiquent 2026.3.0, alors que la racine du package affiche 2026.4.0, ce qui laisse penser qu’une couche malveillante a été ajoutée depuis l’extérieur, hors du pipeline de build légitime.
Mesures de réponse
S’il existe un historique d’installation de cette version, il faut considérer que tous les identifiants de cet hôte ont été compromis.
npm uninstall -g @bitwarden/clipuis nettoyage du cache- Rotation complète des GitHub PAT, tokens npm et clés d’accès AWS
- Vérification des journaux d’audit Azure Key Vault / GCP Secret Manager
- Contrôle d’éventuelles exécutions non autorisées dans les workflows GitHub Actions
- Blocage réseau de
audit.checkmarx.cxet94.154.172.43 - Vérification d’une éventuelle exposition d’informations sensibles dans les fichiers de configuration d’outils IA (Claude, Kiro, etc.)
Il s’agit d’une attaque sophistiquée qui va bien au-delà d’un simple voleur d’identifiants npm, en combinant compromission de la supply chain, vol multicouche de secrets et militarisation de l’infrastructure GitHub.
4 commentaires
Le slogan du site de l’entreprise m’a paru vide de sens, donc je me suis désinscrit.
Ça fait froid dans le dos ;; je l’utilisais tous les jours, et heureusement la version Homebrew n’a pas été compromise.
Pfiou… je vais sans doute soit supprimer toutes les bibliothèques npm globales pour commencer, soit désactiver les scripts pre/postinstall.
Homebrew a changé de fonctionnement pour désactiver par défaut
postinstallet ne l’autoriser qu’à titre d’exception. Je ne sais pas s’il faut parler de chance, mais comme je mets à jour via les tags du dépôt sans passer par npm, cette version m’a épargné. Récemment, il y a aussi eu un cooldown sur npm, donc même si j’avais regardé du côté de npm, il est probable que cela n’aurait pas été publié.Waouh, c’est assez choquant.