Oui, un simple npm install peut compromettre votre entreprise : les scripts d'installation des paquets s'exécutent automatiquement sur la machine du développeur ou du serveur de CI, avec ses droits, ses variables d'environnement et ses secrets. Un paquet malveillant — ou un paquet légitime dont le mainteneur a été piraté — peut ainsi voler des identifiants, des clés cloud ou des tokens en quelques secondes, sans qu'aucune ligne de votre propre code ne soit en cause. La bonne nouvelle : des mesures simples réduisent drastiquement ce risque.
Pourquoi l'écosystème open source est devenu une cible de choix
Attaquer une entreprise bien défendue est coûteux. Compromettre un paquet open source utilisé par des milliers de projets, c'est ouvrir des milliers de portes d'un coup. Trois mécanismes dominent :
- Les hooks d'installation : npm exécute automatiquement les scripts preinstall et postinstall déclarés par chaque dépendance. C'est du code arbitraire lancé sur votre machine au moment même de l'installation, avant toute revue.
- Le typosquatting : des paquets aux noms quasi identiques à des bibliothèques populaires, qui comptent sur une faute de frappe ou une suggestion d'IA approximative pour être installés.
- Les mainteneurs compromis : un compte npm piraté par phishing permet de publier une version piégée d'un paquet parfaitement légitime, récupérée automatiquement par tous les projets qui acceptent les mises à jour mineures.
Des précédents bien réels
Les cas publics ne manquent pas. En 2018, event-stream, téléchargé des millions de fois par semaine, a été piégé après qu'un attaquant a gagné la confiance du mainteneur pour cibler des portefeuilles de cryptomonnaies. En 2021, ua-parser-js a diffusé un mineur de cryptomonnaie et un voleur de mots de passe après le piratage du compte de son auteur. En 2025, la compromission de paquets parmi les plus téléchargés de l'écosystème via le phishing d'un mainteneur, puis le ver auto-répliquant Shai-Hulud qui volait les tokens npm pour se propager de paquet en paquet, ont montré que le phénomène change d'échelle. Chaque vague suit le même schéma : un maillon de confiance cède, et l'attaque descend la chaîne jusqu'à vos machines.
Retour d'expérience : le preinstall.js qui ne devait pas être vu
Lors d'une reprise de projet pour un client, notre équipe a appliqué un réflexe systématique : ne jamais lancer npm install sur un dépôt inconnu avant d'avoir inspecté ses scripts d'installation. Le package.json déclarait un hook preinstall pointant vers un fichier preinstall.js. Premier signal d'alerte : rien dans le projet ne justifiait un tel hook.
Deuxième signal, plus subtil : le fichier semblait court et anodin, mais son poids en octets ne correspondait pas du tout à son contenu apparent. L'analyse hexadécimale a révélé la supercherie : des milliers de sélecteurs de variation Unicode — des caractères invisibles à l'écran — encodaient une charge utile dissimulée dans ce qui ressemblait à un simple fichier de configuration. Une fois décodée dans un environnement isolé, sans jamais l'exécuter, la charge s'est révélée être un infostealer : collecte des identifiants du navigateur, des portefeuilles crypto et des variables d'environnement.
Détail révélateur du niveau de sophistication : le malware ne contenait pas l'adresse de son serveur de commande en clair. Il la récupérait en lisant une transaction sur une blockchain publique servant de dead-drop — un point de rendez-vous impossible à faire fermer, que l'attaquant peut mettre à jour en publiant une nouvelle transaction. L'équipe a neutralisé le hook, purgé l'historique, fait tourner l'intégralité des secrets potentiellement exposés et vérifié qu'aucun poste n'avait exécuté l'installation. Coût de la détection : une heure de vigilance. Coût évité : la compromission des accès de toute une équipe.
Les bonnes pratiques qui changent tout
Bloquer l'exécution automatique
- Configurez --ignore-scripts par défaut (dans le .npmrc du projet ou de la machine) : les scripts d'installation ne s'exécutent plus qu'explicitement, après revue.
- Avant toute reprise de projet ou ajout de dépendance, inspectez les hooks preinstall, install et postinstall du package.json et les fichiers qu'ils référencent.
Verrouiller et auditer les versions
- Committez toujours le lockfile et installez avec npm ci en CI : vous exécutez exactement les versions revues, pas la dernière publication d'un mainteneur potentiellement piraté.
- Auditez régulièrement les dépendances (npm audit, outils d'analyse de composition logicielle) et méfiez-vous des paquets récents, peu téléchargés ou aux noms proches de bibliothèques connues.
- Évitez les montées de version automatiques immédiates : laisser quelques jours entre la publication d'une version et son adoption laisse le temps à l'écosystème de détecter les compromissions.
Isoler et cloisonner
- Exécutez la CI dans des environnements jetables et cloisonnés, avec des secrets à portée minimale et à durée de vie courte.
- Sur les postes de développement, limitez ce qu'un script peut voler : gestionnaire de secrets plutôt que fichiers .env garnis, tokens npm à privilèges réduits, MFA sur les comptes des registres.
Compromission suspectée : les premiers gestes
- Débranchez la machine du réseau sans la réinitialiser, pour préserver les preuves.
- Considérez comme volés tous les secrets accessibles depuis ce poste : tokens npm et cloud, clés SSH, mots de passe du navigateur, sessions actives. Révoquez et faites-les tourner immédiatement.
- Identifiez le paquet et la version en cause via le lockfile, et vérifiez quels autres postes ou pipelines l'ont installé.
- Surveillez les journaux d'accès des services critiques sur la période d'exposition.
La supply chain logicielle est devenue un terrain d'attaque à part entière, et aucune équipe ne peut auditer seule des milliers de dépendances transitives. Instaurer les bons garde-fous, puis savoir réagir vite le jour où un doute apparaît, relève d'une compétence spécifique — celle qu'apporte un partenaire technique rompu à l'analyse de code malveillant et à la réponse à incident.
