Attaque supply chain npm sur Axios : Versions malveillantes déposent un cheval de Troie d'accès à distance

Attaque supply chain npm sur Axios : Versions malveillantes déposent un cheval de Troie d'accès à distance

lschvn

Deux versions malveillantes d'axios — une bibliothèque téléchargée plus de 300 millions de fois chaque semaine, profondément embed dans l'écosystème Node.js — ont été publiées sur npm le 31 mars 2026, et détectées en quelques heures. axios@1.14.1 et axios@0.30.4 étaient livrées avec une dépendance cachée qui ne faisait rien d'autre qu'exécuter un dropper postinstall. Le dropper récupérait des payloads de deuxième étape spécifiques au système d'exploitation depuis un serveur live de commande et contrôle, puis s'effaçait et remplaçait son propre manifest pour cacher les preuves.

Si vous avez installé l'une de ces versions, supposez que votre système est compromis.

L'attaque en chiffres

  • 2 versions malveillantes publiées (1.14.1 et 0.30.4)
  • ~3 heures ces versions étaient en ligne sur npm avant suppression
  • ~300M téléchargements hebdomadaires d'axios (rayon de souffle enormous)
  • 3 cibles OS (macOS, Windows, Linux) — tous les payloads pré-construits
  • 18 heures l'attaquant a préparé l'infrastructure avant de déclencher

Comment l'attaque a fonctionné

Étape 1 — Détournement du compte mainteneur

L'attaquant a compromis le compte npm de jasonsaayman, le mainteneur principal d'axios. Il a changé l'email enregistré pour une adresse ProtonMail contrôlée par l'attaquant, puis publié des builds malveillants manuellement via npm CLI — contournant le pipeline CI/CD normal de GitHub Actions du projet. Ce type de compromis au niveau du compte est un rappel de pourquoi le shift de l'écosystème JavaScript vers les OIDC Trusted Publishers compte : la provenance de publication cryptographique rend plus difficile pour un attaquant de faire passer un paquet malveillant pour légitime.

Un signal forensic critique : chaque release axios 1.x légitime est publiée via le mécanisme OIDC Trusted Publisher de npm, cryptographiquement lié à un workflow GitHub Actions vérifié. Le malveillant 1.14.1 rompt ce pattern entièrement — pas de trustedPublisher, pas de gitHead, pas de commit ou tag Git correspondant.

// axios@1.14.0 — LÉGITIME
"_npmUser": {
  "name": "GitHub Actions",
  "email": "npm-oidc-no-reply@github.com",
  "trustedPublisher": { "id": "github", ... }
}

// axios@1.14.1 — MALVEILLANT
"_npmUser": {
  "name": "jasonsaayman",
  "email": "ifstap@proton.me"
  // pas de trustedPublisher, pas de gitHead
}

Il n'y a pas de commit ou tag dans le dépôt GitHub axios correspondant à 1.14.1. La release n'existe que sur npm.

Étape 2 — Mise en scène d'une dépendance fantôme

Avant de publier les versions axios backdoorées, l'attaquant a seedé un paquet malveillant sur npm : plain-crypto-js@4.2.1, publié depuis un compte séparé jetable. Ce paquet se faisait passer pour la bibliothèque crypto-js légitime — même description, même attribution d'auteur, même URL de dépôt — mais contenait un hook postinstall dont le seul travail était d'exécuter un dropper.

Un grep à travers les 86 fichiers d'axios@1.14.1 confirme : plain-crypto-js n'est jamais importé ou require()'d nulle part dans le code source axios. Il apparaît dans package.json uniquement pour déclencher le hook postinstall. Zéro ligne de code malveillant n'existe à l'intérieur d'axios lui-même.

Étape 3 — Dropper RAT multi-plateforme

Le script postinstall est un fichier JavaScript heavily obfuscated. Toutes les chaînes sensibles — URL C2, commandes shell, chemins de fichiers — sont XOR-encodées dans un tableau et décodées à l'exécution en utilisant une clé dérivée de la chaîne "OrDeR_7077". Le dropper se divise en trois chemins d'attaque spécifiques au OS :

  • macOS : Télécharge un binaire RAT vers /Library/Caches/com.apple.act.mond (conçu pour imiter un cache système Apple), le rend exécutable, et le lance silencieusement via osascript
  • Windows : Copie PowerShell vers %PROGRAMDATA%\wt.exe ( déguisé en Windows Terminal), dépose un VBScript pour récupérer et exécuter un RAT de deuxième étape
  • Linux : Cible les environnements CI/CD, récupère un RAT basé sur Python

Étape 4 — Auto-destruction

Après avoir déployé le payload de deuxième étape, le dropper se supprime et échange un manifest de paquet propre :

// Le propre code de nettoyage de l'attaquant intégré dans le dropper
// Remplace le package.json malveillant par un décoy propre
rename("package.md", "package.json")  // stub propre écrase les preuves
unlink("setup.js")                    // le dropper s'efface

Un développeur qui inspecte son node_modules après coup ne voit aucune indication que quelque chose s'est mal passé.

Indicateurs de compromission (IOCs)

Paquets malveillants :

  • plain-crypto-js@4.2.1 — dépendance malveillante, dropper RAT postinstall
  • axios@1.14.1 — release 1.x backdoorée
  • axios@0.30.4 — release 0.x legacy backdoorée

Infrastructure C2 :

  • sfrclak.com:8000 — serveur de commande et contrôle (livraison étape 2)
  • Segments de chemin : /6202033, packages.npm.org/product0, packages.npm.org/product1, packages.npm.org/product2

Persistance macOS :

  • /Library/Caches/com.apple.act.mond — binaire RAT déposé sur macOS

Persistance Windows :

  • %PROGRAMDATA%\wt.exe — RAT déguisé en Windows Terminal

Ce que vous devez faire maintenant

  1. Vérifiez votre node_modules pour les versions axios 1.14.1 et 0.30.4. Si présentes, supposez la compromission.
  2. Retrogradez immédiatement vers axios@1.14.0 ou axios@0.30.3 — les dernières versions propres connues.
  3. Auditez vos systèmes pour les IOCs — vérifiez les connexions sortantes inattendues vers sfrclak.com:8000, les tâches cron/planifiées inhabituelles, ou les binaires inconnus dans /Library/Caches (macOS) ou %PROGRAMDATA% (Windows).
  4. Rotatez tous les secrets et identifiants accédés depuis les machines de développement qui ont exécuté npm install pendant la fenêtre où les versions malveillantes étaient en ligne (~31 mars, 00:21–03:15 UTC).
  5. Vérifiez votre workflow de publication npm — assurez-vous que votre projet utilise les OIDC Trusted Publishers pour que les publications manuelles basées sur tokens cassent la chaîne de signature.

Pourquoi cette attaque n'était pas opportuniste

La sophistication opérationnelle ici est notable :

  • L'attaquant a seedé un paquet décoy propre (plain-crypto-js@4.2.0) 18 heures avant la release malveillante, établissant un historique de publication npm pour éviter les alertes de "paquet zero-history"
  • Les deux branches de release 1.x et 0.x ont été touchées 39 minutes d'intervalle pour maximiser la couverture
  • Des payloads séparés ont été pré-construits pour trois systèmes d'exploitation
  • L'URL C2 utilise des segments de chemin liés à la structure du chemin du registre npm — packages.npm.org/product0/1/2 — rendant l'exfiltration ressemble à du trafic npm ordinaire
  • Le dropper utilise le binaire osascript légitime d'Apple sur macOS — pas de binaire malveillant écrit sur le disque avant la validation, rendant la détection EDR plus difficile

C'est du savoir-faire d'attaque supply chain à un niveau précédemment réservé aux opérations sponsorisées par des États, maintenant déployé contre un paquet npm top-10.


Sources : StepSecurity, métadonnées du registre npm, dépôt GitHub axios. L'avis de sécurité axios est disponible dans la base de données des avis de sécurité npm.

Questions fréquentes

Articles connexes

Plus de couverture avec des sujets et tags en commun.

Fuite de Source Map Claude Code : L'agent OS caché, l'automatisation Chrome et les failles de vie privée
security

Fuite de Source Map Claude Code : L'agent OS caché, l'automatisation Chrome et les failles de vie privée

Les développeurs ont découvert que le package npm @anthropic-ai/claude-code@v2.1.88 incluait un fichier source map de production exposant le code source TypeScript complet — révélant une orchestration multi-agents non documentée, un serveur MCP Chrome caché, un moteur de requêtes interne, un système de permissions d'outils, et un système de télémétrie à trois niveaux.
ESLint v10 Supprime la Config Legacy — Et l'Écosystème JS Prend Note
javascript

ESLint v10 Supprime la Config Legacy — Et l'Écosystème JS Prend Note

La plus importante release de breaking changes d'ESLint finalise la flat config, supprime entirely le support eslintrc, et ajoute le suivi des références JSX. Mais la vraie histoire est peut-être ce qui le talonne.
Oxc Construisit Discrètement En Rust Le Toolkit JavaScript Le Plus Rapide — Et Il Est Presque Prêt
javascript

Oxc Construisit Discrètement En Rust Le Toolkit JavaScript Le Plus Rapide — Et Il Est Presque Prêt

Alors qu'ESLint v10 se battait avec le ménage legacy, le projet Oxc a livré un linter 100x plus rapide, un formateur 30x plus rapide que Prettier, et un parser qui laisse SWC dans la poussière. Voici ce qu'est réellement le compilateur d'oxydation JavaScript.

Commentaires

Connexion Connectez-vous pour participer à la conversation.

Pas encore de commentaires. Soyez le premier à partager vos pensées.