Un malware npm déclenché à l’exécution contourne les protections contre les scripts d’installation
Un malware npm dissimulé dans une bibliothèque contourne les protections des scripts d’installation et exfiltre des données via Slack, Telegram et Ethereum.
Texte généré par intelligence artificielle, publié sans relecture humaine. Transparence IA
Image d’illustration générée par IA
Une campagne malveillante visant npm a déplacé sa logique d’exécution des hooks d’installation vers le fonctionnement normal de la bibliothèque, permettant ainsi à des packages de franchir les contrôles conçus pour bloquer les scripts de cycle de vie dangereux.
Les chercheurs de Checkmarx ont centré leur enquête sur indexed-btree, un package conçu pour ressembler à la bibliothèque légitime sorted-btree. Selon les informations publiées sur les conclusions des chercheurs, indexed-btree a atteint environ deux millions de téléchargements hebdomadaires, exposant ainsi un grand nombre d’environnements de développement.
Le package ne s’appuie pas sur preinstall, install ou postinstall. Son chargeur est dissimulé dans BTree.prototype.set(), une opération B-tree normale, et s’active pendant l’exécution de l’application lorsqu’il reçoit une valeur de clé spécifique.
Cette conception exploite un angle mort entre la sécurité de l’installation et la surveillance de l’exécution. Un package npm peut s’installer sans demander l’autorisation d’exécuter un script de cycle de vie, puis lancer du code malveillant ultérieurement, lorsqu’une application appelle les fonctions qu’il exporte.
Le parcours malveillant commence dans une méthode courante de la bibliothèque
L’installation initiale de indexed-btree semble propre, car le package n’utilise pas de scripts de cycle de vie des dépendances pour lancer sa charge utile. Le comportement malveillant ne débute que lorsque le logiciel qui utilise la bibliothèque appelle BTree.prototype.set() avec la valeur de déclenchement requise.
La clé de déclenchement exacte n’a pas été communiquée. Les versions concernées du package n’ont pas non plus été précisées, ce qui complique le périmètre de l’inventaire pour les organisations ayant conservé plusieurs versions dans leurs caches de packages ou leurs fichiers de verrouillage.
Une fois déclenchée, la méthode appelle sharedLoad.min.js, qui contient une charge utile obfusquée de premier niveau. En plaçant ce chargeur dans une opération de structure de données fréquemment utilisée, les auteurs peuvent le dissimuler parmi du code apparemment cohérent avec la fonction annoncée du package.
Checkmarx estime que cette technique peut échapper à de nombreux analyseurs statiques et systèmes classiques d’analyse de contamination. Ces outils peuvent examiner les hooks d’installation, la création de sous-processus suspects ou les flux évidents entre des entrées non fiables et des fonctions dangereuses. Ici, la branche malveillante est enfouie dans une API apparemment légitime et reste inactive jusqu’à ce que les conditions d’exécution soient réunies.
Les opérateurs ont également construit une apparence plus générale de légitimité autour du package. Ils ont créé un dépôt GitHub convaincant, l’ont alimenté avec un historique de commits conçu pour paraître authentique et ont entretenu un compte de développeur soigneusement tenu. Ces signaux peuvent influencer les systèmes automatisés de réputation comme les développeurs qui effectuent une vérification manuelle rapide.
Les contrôles de npm v12 ne couvrent pas l’exécution normale
En juin 2026, GitHub a annoncé des mesures de sécurité pour npm destinées à lutter contre les attaques visant la chaîne logistique logicielle, qui affectaient régulièrement les écosystèmes open source depuis la fin de 2025. Parmi ces mesures, npm v12 bloque les scripts de cycle de vie des dépendances, sauf si l’utilisateur les autorise explicitement.
Les protections limitent également la récupération automatique de dépendances depuis des dépôts Git ou des URL distantes sans autorisation. Ces changements réduisent l’efficacité des packages qui s’exécutent immédiatement pendant l’installation ou récupèrent du code externe au moyen de déclarations de dépendances.
indexed-btree contourne entièrement cette frontière de sécurité.
Comme son chargeur malveillant fait partie du chemin d’exécution normal du package, npm ne rencontre aucun script d’installation nécessitant une autorisation. L’installation peut donc se terminer sans afficher l’avertissement ni demander l’autorisation qu’un défenseur pourrait attendre d’un package malveillant classique.
Il ne s’agit pas d’un contournement de npm v12 au moyen d’une vulnérabilité logicielle. Cela révèle plutôt les limites d’un contrôle concentré sur une seule étape d’exécution. Les restrictions visant les scripts de cycle de vie peuvent empêcher un comportement non autorisé lors de l’installation, mais elles ne permettent pas de déterminer si chaque fonction appelable d’une dépendance est sûre.
Une installation réussie et dépourvue d’avertissement ne constitue donc pas la preuve que le code installé est inoffensif.
La reconnaissance prépare le chargement chiffré sur la blockchain
Après son activation, le malware dresse l’inventaire de l’hôte. Les informations collectées comprennent :
- Architecture du système
- Nom d’hôte
- Informations sur le processeur
- Informations sur la mémoire
- Temps de fonctionnement du système
Il exfiltre ces données par l’intermédiaire de canaux Slack et Telegram codés en dur. Les identifiants précis des canaux, les destinations et les indicateurs réseau n’ont pas été communiqués.
Pour assurer le commandement et le contrôle, l’opération interroge un smart contract Ethereum déployé sur le réseau de test Sepolia. Cette architecture permet aux opérateurs de stocker ou de distribuer des éléments de charge utile via une infrastructure blockchain, plutôt que de dépendre exclusivement d’un serveur de commandement et de contrôle classique.
Le malware utilise l’échange de clés X25519 pour dériver une clé AES. Il déchiffre ensuite une charge utile de deuxième niveau récupérée depuis le smart contract. Le contenu et les capacités complètes de ce deuxième niveau n’ont pas été communiqués ; l’impact confirmé ne doit donc pas être étendu au-delà du mécanisme de distribution et d’exécution observé.
Les enquêteurs ont également identifié un portefeuille Ethereum lié à l’opération, contenant 109 ETH. Rien ne permet actuellement d’établir que ces fonds proviennent d’un vol de cryptomonnaies ou de systèmes compromis par ces packages.
Le malware intègre en outre une fonction de nettoyage contrôlée par l’opérateur. Lorsqu’elle est activée, elle peut supprimer ses fichiers et retirer le déclencheur malveillant du code source du package. Cette capacité peut donner l’impression qu’un environnement précédemment affecté est propre lors d’une inspection ultérieure, en particulier si les données de télémétrie pertinentes concernant les processus, le réseau et le système de fichiers n’ont pas été conservées.
Neuf packages associés ont étendu la portée de la campagne
Checkmarx a établi un lien entre neuf autres packages npm et la même opération. Les neuf packages ont été retirés de npm après leur découverte.
| Package | Téléchargements signalés |
|---|---|
ordered-kv-index |
448 184 |
btree-leaderboard |
493 685 |
priority-slot-queue |
402 860 |
btree-range-store |
468 092 |
btree-core |
1 951 274 |
btree-time-index |
425 312 |
btree-lru-cache |
372 185 |
neighbor-key-map |
366 019 |
sliding-score-window |
448 024 |
Le statut de suppression de indexed-btree lui-même n’a pas été précisé. Son chiffre annoncé d’environ deux millions de téléchargements hebdomadaires ne doit pas non plus être comparé directement aux téléchargements des autres packages ni leur être ajouté, car ces derniers sont présentés comme des nombres de téléchargements signalés sans la même précision hebdomadaire.
Les statistiques de téléchargement indiquent une diffusion, pas une compromission. Elles ne permettent pas de savoir combien de téléchargements ont donné lieu à des installations, combien d’applications ont appelé la méthode modifiée ni combien d’exécutions ont fourni la clé de déclenchement requise.
Les noms des packages laissent néanmoins penser que les auteurs visaient des cas d’usage liés au développement logiciel, notamment les index, les files d’attente, les caches, les maps et les systèmes de scoring. L’exposition potentielle concerne les postes de travail des développeurs, les runners CI, les serveurs de build et d’autres systèmes sur lesquels les dépendances npm s’exécutent avec un accès au code source ou aux identifiants.
Le principal risque dépasse le simple profilage de l’hôte
Aucun score CVSS ni niveau de gravité attribué par un éditeur n’a été communiqué. Il s’agit d’une campagne visant des packages malveillants, et non d’une vulnérabilité classique associée à un identifiant CVE publié.
Sur le plan opérationnel, le risque est élevé, car le code combine une large diffusion, une activation différée à l’exécution, une reconnaissance de l’hôte, le chargement chiffré d’une charge utile de deuxième niveau et la suppression de traces. Un environnement de développement compromis peut exposer davantage que les seules métadonnées système collectées par le premier niveau.
Selon les autorisations locales, un deuxième niveau malveillant pourrait potentiellement accéder à des tokens de publication de packages, à des identifiants de contrôle de code source, à des clés cloud, à des secrets CI, à du matériel de signature ou à la configuration d’applications. L’accès à ces ressources n’a pas été confirmé, mais les organisations doivent les inclure lorsqu’elles déterminent ce qui était accessible au processus concerné.
L’auto-nettoyage complique également le périmètre de l’incident. L’absence de fichiers malveillants lors de l’examen ne prouve pas que l’exécution n’a jamais eu lieu.
Les organisations concernées doivent préserver les éléments de preuve avant toute reconstruction
Les organisations doivent rechercher indexed-btree et les neuf noms associés dans les inventaires de dépendances, les fichiers de verrouillage, les registres internes, les caches de build, les couches de conteneurs et les SBOM. Comme les plages de versions concernées sont inconnues, les enquêteurs ne doivent pas considérer une version donnée comme sûre sans en valider indépendamment le contenu.
Avant de reconstruire les systèmes, les équipes d’intervention doivent préserver les artefacts de packages disponibles, la télémétrie des processus, l’historique des commandes, les journaux réseau, les enregistrements CI et les éléments de preuve du système de fichiers. Sans cela, le mécanisme de nettoyage pourrait effacer les informations nécessaires pour déterminer si le déclencheur d’exécution s’est activé.
Les mesures recommandées sont les suivantes :
- Isoler les systèmes de développement et de build potentiellement concernés.
- Faire tourner tous les secrets accessibles depuis ces environnements, notamment les identifiants de contrôle du code source, de registre, cloud, de déploiement et CI.
- Restaurer les systèmes depuis une sauvegarde connue comme sûre ou une image saine, plutôt que de faire confiance au mécanisme de suppression du malware.
- Rechercher les connexions d’exécution impliquant Slack, Telegram et l’infrastructure Sepolia, en gardant à l’esprit que des outils légitimes peuvent également utiliser ces services.
- Rechercher les échanges de clés X25519 et les activités de déchiffrement AES inattendus associés à Node.js ou aux processus de build concernés.
- Examiner l’exécution des applications, et pas seulement l’installation des packages, afin de repérer les appels aux méthodes de bibliothèque modifiées et le chargement de
sharedLoad.min.js. - Ajouter l’analyse de l’exécution en bac à sable au filtrage des packages, en particulier lorsque les dépendances contiennent du code obfusqué ou modifient des chemins d’API courants.
Le blocage des scripts de cycle de vie reste utile, mais il ne couvre qu’un point de la chaîne d’exécution d’une dépendance. Cette campagne montre que des mainteneurs malveillants peuvent déplacer l’activation dans l’application elle-même, où le code du package bénéficie de la confiance et des accès déjà accordés aux logiciels normaux.
Sources
Cet article est une réécriture originale fondée sur les sources ci-dessous.
