10 bonnes pratiques de sécurité pour npm
Juan Picado
19 février 2019
0 minutes de lectureLes vulnérabilités npm vous préoccupent ? Les bonnes pratiques de sécurité pour npm sont importantes, aussi bien pour les développeurs frontend que backend. L’audit de la sécurité open source est essentiel pour intégrer la sécurité dès le début du cycle de développement. La sécurité des packages npm doit être une priorité, car même l’outil officiel en ligne de commande npm s’est révélé vulnérable.
Dans cette édition de notre aide-mémoire, nous allons nous intéresser à dix bonnes pratiques de sécurité et conseils de productivité pour npm, à l’intention des responsables de projets open source et des développeurs. Commençons notre liste de 10 bonnes pratiques de sécurité pour npm par une erreur classique : des personnes ajoutent leurs mots de passe aux packages npm qu’elles publient !
1. Évitez de publier des secrets dans le registre npm
Que vous utilisiez des clés API, des mots de passe ou d’autres secrets, ils peuvent très facilement se retrouver dans le système de gestion de versions, voire dans un package publié sur le registre npm public. Votre répertoire de travail peut contenir des secrets dans des fichiers dédiés comme .env, qu’il convient d’ajouter à .gitignore pour éviter de les valider dans un SCM. Mais que se passe-t-il lorsque vous publiez un package npm à partir du répertoire du projet ?
La CLI npm regroupe un projet dans une archive tar (tarball) afin de l’envoyer au registre. Les critères suivants déterminent les fichiers et répertoires ajoutés au tarball :
Si un fichier
.gitignoreou.npmignoreexiste, son contenu est utilisé comme modèle d’exclusion lors de la préparation du package pour publication.Si les deux fichiers d’exclusion existent, tout ce qui ne figure pas dans
.npmignoreest publié dans le registre. Cette situation, souvent source de confusion, peut entraîner la fuite de secrets. Les développeurs peuvent mettre à jour le fichier.gitignore, mais oublier également de mettre à jour.npmignore: un fichier potentiellement sensible ne sera alors pas envoyé au système de gestion de versions, mais sera tout de même inclus dans le package npm.
Une autre bonne pratique consiste à utiliser la propriété files dans package.json. Elle fonctionne comme une liste d’autorisation et spécifie le tableau des fichiers à inclure dans le package créé et installé (alors que le fichier d’exclusion fonctionne comme une liste de blocage). La propriété files et un fichier d’exclusion peuvent être utilisés ensemble pour déterminer les fichiers à inclure ou à exclure explicitement du package. Dans ce cas, la propriété files de package.json prévaut sur le fichier d’exclusion.
Lors de la publication d’un package, la CLI npm affiche en détail l’archive en cours de création. Pour redoubler de prudence, ajoutez l’argument --dry-run à votre commande de publication afin de vérifier d’abord la création du tarball sans le publier réellement dans le registre.
En janvier 2019, npm a annoncé sur son blog avoir ajouté un mécanisme qui révoque automatiquement un jeton lorsqu’il détecte qu’un package a été publié avec celui-ci.
2. Appliquez le fichier de verrouillage
Nous avons accueilli à bras ouverts l’arrivée des fichiers de verrouillage des packages, qui ont apporté des installations déterministes dans différents environnements et l’application des dépendances attendues dans le cadre du travail en équipe. Tout va bien ! C’est ce que je croyais… Que se serait-il passé si j’avais apporté une modification au fichier package.json du projet, mais oublié de valider le fichier de verrouillage en même temps ?
Yarn et npm se comportent de la même façon lors de l’installation des dépendances. Lorsqu’ils détectent une incohérence entre le fichier package.json du projet et le fichier de verrouillage, ils compensent cette modification en se basant sur le manifeste package.json et installent des versions différentes de celles consignées dans le fichier de verrouillage.
Cette situation peut être dangereuse pour les environnements de compilation et de production, car ils risquent de récupérer des versions de packages imprévues, rendant ainsi inutile tout l’intérêt du fichier de verrouillage.
Heureusement, il est possible de demander à Yarn et à npm de respecter un ensemble précis de dépendances et de versions en se référant au fichier de verrouillage. Toute incohérence entraîne l’arrêt de l’installation. Voici les commandes à exécuter :
Si vous utilisez Yarn, exécutez
yarn install --frozen-lockfile.Si vous utilisez npm, exécutez
npm ci.
3. Réduisez la surface d’attaque en ignorant les scripts d’exécution
La CLI npm utilise les scripts d’exécution des packages. Si vous avez déjà exécuté npm start ou npm test, vous avez également utilisé ces scripts. La CLI npm s’appuie sur les scripts qu’un package peut déclarer et permet aux packages de définir des scripts à exécuter à des étapes précises de leur installation dans un projet. Par exemple, certaines entrées de hooks de script peuvent être des scripts postinstall, exécutés par le package installé pour effectuer des tâches de maintenance.
Cette fonctionnalité peut être détournée par des acteurs malveillants qui créent ou modifient des packages pour exécuter des commandes arbitraires à leur installation. Nous en avons déjà vu quelques exemples : l’incident populaire lié à eslint-scope, qui a dérobé des jetons npm, et celui de crossenv, ainsi que 36 autres packages ayant exploité une attaque par typosquattage sur le registre npm.
Appliquez ces bonnes pratiques de sécurité pour npm afin de réduire la surface d’attaque liée aux modules malveillants :
Vérifiez toujours les modules tiers que vous installez et faites preuve de diligence raisonnable pour confirmer leur fiabilité et leur crédibilité.
Évitez de passer aveuglément aux nouvelles versions ; laissez aux nouvelles versions des packages le temps de circuler avant de les essayer.
Avant toute mise à niveau, consultez le journal des modifications et les notes de version de la version concernée.
Lors de l’installation de packages, ajoutez le suffixe
--ignore-scriptspour désactiver l’exécution des scripts des packages tiers.Envisagez d’ajouter
ignore-scriptsau fichier de projet.npmrcou à votre configuration npm globale.
4. Évaluez l’état de santé de votre projet npm
Dépendances obsolètes
Se précipiter pour constamment mettre à niveau les dépendances vers leurs versions les plus récentes n’est pas forcément une bonne pratique si vous ne consultez pas les notes de version et les modifications du code, et ne testez pas les nouvelles versions de manière approfondie. Cela dit, conserver des dépendances obsolètes sans les mettre à niveau, ou attendre trop longtemps pour le faire, peut aussi causer des problèmes.
La CLI npm peut vous renseigner sur l’ancienneté des dépendances que vous utilisez au regard de leur version sémantique. Exécutez npm outdated pour voir quels packages ne sont pas à jour :

« Les dépendances affichées en jaune correspondent au versionnage sémantique spécifié dans le manifeste package.json ; celles en rouge indiquent qu’une mise à jour est disponible. Le résultat affiche également la dernière version de chaque dépendance. »
Appelez le docteur
Avec la variété des gestionnaires de packages Node.js et des versions de Node.js que vous avez peut-être installées dans votre chemin d’accès, comment vérifier que votre installation npm et votre environnement fonctionnent correctement ? Que vous utilisiez la CLI npm dans un environnement de développement ou dans un environnement d’intégration continue (CI), il est important de vérifier que tout fonctionne comme prévu.
Appelez le docteur ! La CLI npm intègre un outil de diagnostic qui évalue l’état de votre environnement pour garantir le bon fonctionnement de npm. Exécutez npm doctor pour vérifier votre configuration npm :
Vérifier que le registre npm officiel est accessible et afficher le registre actuellement configuré.
Vérifier que Git est disponible.
Vérifier les versions installées de npm et de Node.js.
Vérifier les autorisations sur les différents dossiers, notamment les dossiers
node_moduleslocaux et globaux, ainsi que celui utilisé pour le cache des packages.Vérifier que les sommes de contrôle du cache local des modules npm sont correctes.
5. Auditez les vulnérabilités des dépendances open source
L’écosystème npm est le plus grand référentiel de bibliothèques applicatives parmi tous les écosystèmes de langages. Le registre et les bibliothèques qu’il héberge sont au cœur du travail des développeurs JavaScript, qui peuvent tirer parti du travail déjà réalisé par d’autres et l’intégrer à leur base de code. Toutefois, l’adoption croissante des bibliothèques open source dans les applications entraîne un risque accru d’introduction de vulnérabilités de sécurité.
De nombreux packages npm populaires se sont révélés vulnérables et peuvent présenter un risque important si les dépendances de votre projet ne font pas l’objet d’un audit de sécurité adéquat. Parmi les exemples : npm request, superagent, mongoose, et même des packages liés à la sécurité comme jsonwebtoken et npm validator.
La sécurité ne se limite pas à rechercher les vulnérabilités lors de l’installation d’un package. Pour être adoptée efficacement tout au long du cycle de développement logiciel, elle doit aussi s’intégrer aux workflows des développeurs et faire l’objet d’une surveillance continue une fois le code déployé.
Rechercher les vulnérabilités
Pour appliquer les bonnes pratiques de sécurité npm, recherchez les vulnérabilités avec Snyk à l’aide de la commande suivante :
Lorsque vous exécutez un test Snyk, Snyk signale les vulnérabilités détectées et affiche les chemins vulnérables afin que vous puissiez parcourir l’arborescence des dépendances et comprendre quel module a introduit une vulnérabilité. Surtout, Snyk vous propose des conseils de correction concrets : vous pouvez mettre à niveau vers une version corrigée grâce à une pull request automatisée ouverte par Snyk dans votre dépôt, ou appliquer un correctif fourni par Snyk pour atténuer la vulnérabilité lorsqu’aucune correction n’est disponible. Snyk recommande une mise à niveau optimisée, en proposant la mise à jour semver minimale possible pour le package vulnérable.
Surveillez les vulnérabilités découvertes dans les bibliothèques open source
Le travail de sécurisation ne s’arrête pas là.
Qu’en est-il des vulnérabilités découvertes dans les dépendances d’une application après son déploiement ? C’est là qu’interviennent l’importance de la surveillance de sécurité et son intégration étroite au cycle de développement du projet.
Nous vous recommandons d’intégrer Snyk à votre système de gestion du code source (SCM), comme GitHub ou GitLab, afin que Snyk surveille activement vos projets et :
Ouvre automatiquement des PR pour mettre à niveau ou corriger les dépendances vulnérables à votre place
Analysez et détectez les vulnérabilités dans les bibliothèques open source qu’une pull request a pu introduire
Si vous ne pouvez pas intégrer Snyk à un SCM, vous pouvez également surveiller des instantanés de vos projets envoyés depuis l’outil CLI Snyk. Il vous suffit d’exécuter :
En quoi Snyk se distingue-t-il de npm audit ?
Nous vous invitons à lire un article publié par Nearform qui compare les différences entre l’audit npm et Snyk.
La base de données des vulnérabilités de Snyk fournit des données exhaustives sur les vulnérabilités grâce à son système de veille sur les menaces. Elle offre une meilleure couverture et permet de détecter et de signaler les vulnérabilités qui n’ont pas encore reçu de CVE. Par exemple, 72 % des vulnérabilités figurant dans les avis npm ont d’abord été ajoutées à la base de données des vulnérabilités de Snyk Open Source.
6. Utilisez un proxy npm local
Le registre npm est la plus grande collection de packages accessible à tous les développeurs JavaScript et héberge également la plupart des projets open source destinés aux développeurs web. Mais vos besoins en matière de sécurité, de déploiement ou de performances peuvent parfois être différents. Dans ce cas, npm vous permet de choisir un autre registre :
Lorsque vous exécutez npm install, npm communique automatiquement avec le registre principal pour résoudre toutes vos dépendances. Si vous souhaitez utiliser un autre registre, la procédure est très simple :
Exécutez
npm set registrypour définir un registre par défaut.Utilisez l’argument
--registrypour spécifier un registre ponctuellement.
Verdaccio est un registre privé simple et léger, qui ne nécessite aucune configuration. Son installation est tout aussi simple :

Héberger votre propre registre n’a jamais été aussi simple ! Découvrons les principales fonctionnalités de cet outil :
Il prend en charge le format du registre npm, y compris les fonctionnalités de packages privés, la prise en charge des scopes, le contrôle d’accès aux packages et l’authentification des utilisateurs dans l’interface web.
Il permet de connecter des registres distants et d’acheminer chaque dépendance vers différents registres, tout en mettant les archives tar en cache. Pour éviter les téléchargements en double et économiser de la bande passante sur vos serveurs de développement local et d’intégration continue, vous devriez utiliser un proxy pour toutes les dépendances.
Par défaut, il utilise htpasswd comme fournisseur d’authentification, mais prend également en charge GitLab, Bitbucket et LDAP. Vous pouvez aussi utiliser votre propre fournisseur.
Il est facile à faire évoluer en utilisant un autre fournisseur de stockage.
Si votre projet repose sur Docker, utiliser l’image officielle est le meilleur choix.
Il permet de configurer très rapidement des environnements de test et s’avère pratique pour tester de grands projets monorepo.
Son exécution est assez simple :
Si vous utilisez verdaccio comme registre privé local, pensez à configurer vos packages pour imposer leur publication sur le registre local et éviter que les développeurs ne les publient accidentellement sur un registre public. Pour cela, ajoutez ce qui suit à package.json :
Votre registre est opérationnel — youpi ! Pour publier un package, utilisez simplement la commande npm npm publish et vous pourrez le partager avec le monde entier.
7. Divulguer les vulnérabilités de sécurité de manière responsable
La divulgation publique de vulnérabilités de sécurité sans avertissement préalable ni mesures d’atténuation adaptées permettant aux utilisateurs de se protéger peut représenter une menace sérieuse.
Il est recommandé aux chercheurs en sécurité de suivre un programme de divulgation responsable, c’est-à-dire un ensemble de processus et de directives visant à mettre en relation les chercheurs avec le fournisseur ou le responsable de la maintenance de l’actif vulnérable, afin de communiquer la vulnérabilité, son impact et son applicabilité. Une fois la vulnérabilité correctement évaluée, le fournisseur et le chercheur coordonnent un correctif et une date de publication, afin de proposer une mise à niveau ou une solution aux utilisateurs concernés avant que le problème de sécurité ne soit rendu public.
La sécurité est trop importante pour être négligée ou traitée de manière contraire à l’éthique. Chez Snyk, nous accordons une grande valeur à la communauté de la sécurité et pensons que la divulgation responsable des vulnérabilités dans les packages open source contribue à garantir la sécurité et la confidentialité des utilisateurs.
L’équipe de recherche en sécurité de Snyk collabore régulièrement avec la communauté dans le cadre de programmes de bug bounty, comme dans le cas de f2e-server, qui a donné lieu à des centaines de divulgations par la communauté. Snyk entretient également un partenariat étroit avec des chercheurs universitaires, notamment à Virginia Tech, afin de mettre à disposition son expertise en sécurité et de coordonner les échanges avec les fournisseurs et les responsables de la maintenance de la communauté.
Nous vous invitons à collaborer avec nous et à faire appel à notre aide pour le processus de divulgation :
Signalez les vulnérabilités de manière responsable sur https://snyk.io/vulnerability-disclosure ou par e-mail à security@snyk.io
Vous pouvez consulter notre politique de divulgation ici.
8. Activez l’authentification à deux facteurs
En octobre 2017, npm a officiellement annoncé la prise en charge de l’authentification à deux facteurs (2FA) pour les développeurs qui utilisent le registre npm afin d’héberger leurs packages privés et open source.
Bien que le registre npm prenne en charge la 2FA depuis un certain temps, son adoption semble lente. L’incident eslint-scope de mi-2018 en est un exemple : le vol du compte d’un développeur de l’équipe ESLint a permis à des acteurs malveillants de publier une version malveillante d’eslint-scope.
** AVERTISSEMENT DE SÉCURITÉ URGENT ** À partager.
Aujourd’hui, la version 3.7.2 d’eslint-scope (https://t.co/Gkc9XhDRN6) a été identifiée comme contenant un code malveillant qui vole vos identifiants NPM. Agissez dès maintenant si vous utilisez la version 3.7.2.
Entrée dans la base de données Snyk : https://t.co/dAhhA3cZQP
— Snyk (@snyksec) 12 juillet 2018
Activer la 2FA est un moyen simple et efficace d’améliorer la sécurité de npm. Le registre propose deux modes d’activation de la 2FA sur un compte utilisateur :
Autorisation uniquement — lorsqu’un utilisateur se connecte à npm via le site web ou la CLI, ou effectue d’autres actions telles que la modification des informations de son profil.
Autorisation et écriture — actions sur le profil et la connexion, ainsi que les actions d’écriture comme la gestion des jetons et des packages, avec une prise en charge limitée des informations de visibilité des équipes et des packages.
Munissez-vous d’une application d’authentification, comme Google Authenticator, que vous pouvez installer sur un appareil mobile, et vous êtes prêt à commencer. Pour activer facilement la protection renforcée de votre compte par 2FA, passez par l’interface utilisateur de npm. Si vous préférez la ligne de commande, vous pouvez également activer la 2FA à l’aide d’une version prise en charge du client npm (>=5.5.1) :
Suivez les instructions de la ligne de commande pour activer la 2FA et enregistrer les codes d’authentification d’urgence. Pour activer la 2FA uniquement lors de la connexion et de la modification du profil, remplacez auth-and-writes par auth-only dans le code ci-dessus.
9. Utilisez des jetons d’accès npm
Chaque fois que vous vous connectez avec la CLI npm, un jeton est généré pour votre compte et vous authentifie auprès du registre npm. Les jetons facilitent l’exécution d’actions liées au registre npm dans les processus d’intégration continue et les procédures automatisées, comme l’accès à des modules privés sur le registre ou la publication de nouvelles versions à partir d’une étape de build.
Vous pouvez gérer les jetons sur le site web du registre npm ou à l’aide du client en ligne de commande npm. Voici un exemple de création, avec la CLI, d’un jeton en lecture seule limité à une plage d’adresses IPv4 spécifique :
Pour vérifier les jetons créés pour votre compte ou révoquer des jetons en cas d’urgence, utilisez respectivement npm token list ou npm token revoke.
Respectez cette bonne pratique de sécurité npm en protégeant vos jetons npm et en limitant leur exposition.
10. Comprenez les conventions de nommage des modules et les attaques par typosquatting
Le nommage d’un module est la première étape de la création d’un package. Mais avant d’arrêter votre choix, sachez que npm impose plusieurs règles concernant les noms de packages :
Il ne doit pas dépasser 214 caractères
Il ne peut pas commencer par un point ou un trait de soulignement
Le nom ne peut contenir aucune majuscule
Aucun espace à la fin
Uniquement des minuscules
Certains caractères spéciaux sont interdits : « ~\’!()* »)
Ne peut pas commencer par . ou _
Ne peut pas contenir node_modules ni favicon.ico, car ces noms sont interdits
Même si vous respectez ces règles, sachez que npm utilise un mécanisme de détection du spam lors de la publication de nouveaux packages. Celui-ci s’appuie sur un score et vérifie si le nom du package enfreint les conditions d’utilisation. En cas d’infraction, le registre peut refuser la requête.
Le typosquatting est une attaque qui exploite les erreurs des utilisateurs, comme les fautes de frappe. Les acteurs malveillants peuvent ainsi publier sur le registre npm des modules malveillants dont le nom ressemble à celui de modules populaires existants.
Nous avons suivi des dizaines de packages malveillants dans l’écosystème npm ; certains ont également été repérés sur le registre Python PyPI. Parmi les incidents les plus notables figurent ceux impliquant cross-env, event-stream et eslint-scope.

Les attaques par typosquatting visent souvent les identifiants des utilisateurs, car tout package peut accéder aux variables d’environnement via la variable globale process.env. Parmi les autres cas observés par le passé, citons event-stream : l’attaque visait les développeurs dans l’espoir d’injecter du code malveillant dans le code source d’une application.
Pour conclure cette liste de dix bonnes pratiques de sécurité npm, voici quelques conseils pour réduire le risque de telles attaques :
Soyez particulièrement vigilant lorsque vous copiez-collez des instructions d’installation de packages dans le terminal. Vérifiez dans le dépôt du code source et sur le registre npm qu’il s’agit bien du package que vous souhaitez installer. Vous pouvez vérifier les métadonnées du package avec
npm infopour obtenir plus d’informations sur les contributeurs et les dernières versions.Par défaut, déconnectez-vous de npm dans vos tâches quotidiennes afin que vos identifiants ne deviennent pas le maillon faible permettant de compromettre facilement votre compte.
Lors de l’installation de packages, ajoutez l’option
--ignore-scriptspour réduire le risque d’exécution de commandes arbitraires. Exemple :npm install my-malicious-package --ignore-scripts
Pensez à imprimer la fiche récapitulative et à l’afficher quelque part pour vous rappeler les bonnes pratiques de sécurité npm à suivre si vous développez en JavaScript ou utilisez simplement npm pour le plaisir.
Lancez-vous dans les compétitions Capture The Flag
Apprenez à résoudre des défis de capture du drapeau en regardant à la demande notre atelier virtuel d’initiation.