Je n’ai même pas eu le temps de faire une nouvelle note depuis la dernière attaque. Cette fois ça passe par un script postinstall
(que Deno, Bun et pnpm ignorent, mais que npm et yarn exécutent automatiquement), et ça vient aussi contaminer tous les packages que la machine infectée peut déployer. Résultat : Plus de 500 packages actuellement compromis.
Plus d’informations :
Sûrement cette fois-ci ça va faire bouger l’écosystème. Au moins que npm et yarn arrêtent d’exécuter les scripts postinstall
automatiquement, mais aussi :
- Mettre en place de bonnes pratiques pour éviter de se faire sniffer bêtement des logins/tokens (voir revoir complètement la manière dont on s’authentifie) : pourquoi je télécharge plein de code non-validé sur la même machine (et sous le même compte utilisateur) où sont toutes mes clés SSH et mots de passe ?
- Resserrer les permissions (Node commence à mettre en place un flag —permissions à l’image de Deno) : Pourquoi est-ce qu’un script postinstall peut lire tous les fichiers de ma machine et accéder à internet sans rien demander ? Pourquoi ma CI peut aller taper dans une API inconnue au bataillon ?
- Ne pas télécharger immédiatement la dernière version publiée il y a 5 minutes, et/ou ne télécharger que des versions qui ont au moins été scannées (un gros bloc de code obfusqué doit définitivement balancer des alertes). Ces scans et audits sont d’utilité publique au même niveau que les certificats de transparence, mais ils n’ont pas la même place dans l’interface.
- Générer des SBOMs et faire un monitoring continu (dependabot sur GitHub fait déjà une bonne partie du travail, mais c’est limité à GitHub et c’est souvent de faux positifs)
- Prendre conscience de toutes les dépendances qu’on accepte dans son projet, les limiter et/ou les vendor
- …
C’est un jeu du chat et de la souris, mais il y a des trous béants qui n’ont pas raison d’être, et d’autres trous qu’on perce nous-même au nom du confort ou de la flemme ou d’outils mal conçus.
Edit : Tiens, je viens de voir que pnpm a introduit un paramètre minimumReleaseAge
dans la version 10.16 (il y a 5 jours) pour empêcher l’installation d’une version d’un package trop récente. GitHub a introduit une option similaire pour dependabot, et c’est aussi possible dans renovatebot.