Maxime Dupont
OVHcloud
🦩 Maxime Dupont 🦩
OVHcloud · Alternatiba · Shifters
Jardinage · Bricolage · Jeux de société · Cinéma
maximedupont.fr - m.dupont103@gmail.com
Vous n'attaquez pas la cible directement. Vous compromettez un de ses fournisseurs.
Une première attaque a eu lieu en septembre 2025. Deux mois plus tard, une deuxième version voit le jour.
| Métrique | Valeur |
|---|---|
| Paquets npm compromis | 796 |
| Téléchargements hebdo cumulés | 20 millions+ |
| Repos GitHub exposés | 25 000+ |
| Secrets exfiltrés | 294 842 |
| Durée de l'attaque | 48h (21-23 nov.) |
Zapier, PostHog, Postman, ENS Domains
Compromettre un premier package npm (ingénierie sociale)
Le paquet compromis contient un preinstall script dans package.json :
{
"scripts": {
"preinstall": "node setup_bun.js"
}
} preinstall ?setup_bun.js est volontairement non obfusqué et bien documenté — il se fait passer pour un installeur légitime du runtime BunL'attaquant joue sur la confiance : le code a l'air normal à première vue.
setup_bun.js télécharge et exécute bun_environment.js — un
fichier de 10 Mo, obfusqué.
.env, configs git,
historiquecloud.json, environment.json, actionsSecrets.jsonS'il trouve un token npm valide → il republie les paquets accessibles avec le payload malicieux inclus. Le ver se propage.
pas de serveur C2 (Command and Control) classique.
Si le malware ne trouve ni token npm, ni token GitHub :
C'est la première supply chain attack npm avec un mécanisme de sabotage punitif.
On utilise (tous) npm et si on n'utilise pas npm, on en utilise d'autres
Luck isn't a security strategy.
Ryan Sobol — Principal Software Engineer at the Seattle Times
Connaissez votre écosystème !
Veillez ! → Hacker news
Analyse de vulnérabilité sur la CI, Dépendabot, Artifactory, ...
Si vous découvrez que vous êtes compromis :
| Action | Détail |
|---|---|
| Ne pas supprimer le repo malveillant | Le privatiser immédiatement pour stopper l'exposition |
| Désactiver les workflows malicieux | Vérifier tous les self-hosted runners |
| Supprimer les paquets infectés | Reverter aux versions saines connues, surtout sur les registres internes |
| Révoquer TOUS les secrets | Pas seulement ceux trouvés dans le repo — tous |
| Auditer les accès | Qui a installé quoi, quand, sur quelle machine |
Le choix du package manager est la première ligne de défense.
| Gestionnaire de paquets | Version | Date |
|---|---|---|
| Yarn | v2.0 | Jan. 2020 |
| Bun* | v1.0 | Sept. 2023 |
| pnpm** | v10.0 | Jan. 2025 |
| npm*** | - | - |
strictDepBuilds permet de faire échouer l'installation--ignore-scripts.Contrôler quels paquets sont autorisés à exécuter des lifecycle scripts.
| Gestionnaire de paquets | Paramètre | Disponible depuis |
|---|---|---|
| Yarn | enableScripts (per-dep) | v2.0 (Jan. 2020) |
| Bun | trustedDependencies (per-dep) | v1.1 (Avr. 2024) |
| pnpm | onlyBuiltDependencies | v9.1 (Mai 2024) |
| npm | - | - |
Bloquer l'installation de versions publiées trop récemment — le temps que la communauté détecte les paquets malicieux.
# .npmrc (pnpm)
minimum-release-age=3d
minimum-release-age-exclude=my-org Les 796 paquets compromis ont été publiés et détectés en 48h — un délai de 3 jours les aurait tous bloqués.
| Gestionnaire de paquets | Paramètre | Disponible depuis |
|---|---|---|
| npm | minimum-release-age | v11.11 (feb. 2026) |
| pnpm | minimum-release-age | v10.16 (sept. 2025) |
| Yarn | npmMinimalAgeGate | v4.10.0 (sept. 2025) |
| Bun | Support natif | v1.3 (oct. 2025) |
Ce contrôle bloque l’installation lorsqu’une version d’un package a une authentification plus faible que les versions publiées précédemment.
| Gestionnaire de paquets | Paramètre | Disponible depuis |
|---|---|---|
| pnpm | trustPolicy: "no-downgrade" | v9 (~2024) |
| npm | — | — |
| Yarn | — | — |
| Bun | — | — |
Si vous utilisez npm :
npm config set ignore-scripts true # Désactive tous les lifecycle scripts
npm install --ignore-scripts # Par installation En CI/CD, toujours builder avec --ignore-scripts et exécuter les scripts nécessaires
manuellement après audit.
Posez vos questions — sur l'attaque, les mesures de protection.