Skip to main content

Le package npm faker et la disparition inattendue des bibliothèques open source

Écrit par
blog feature snyk open source blue

2 septembre 2022

0 minutes de lecture

Où vont mourir les dépendances open source, et pourquoi finissent-elles par disparaître ? Qu’est-il arrivé au module npm faker ? Cela peut-il se reproduire ? Découvrez comment les bibliothèques open source connaissent leur heure de gloire, puis arrivent en fin de vie. Je vous présenterai également quelques enseignements utiles aux développeurs et aux ingénieurs des opérations.

Je souhaite vous raconter plusieurs histoires issues des écosystèmes JavaScript et PHP, où la chaîne d’approvisionnement logicielle a été brutalement perturbée en raison de préoccupations climatiques et environnementales, ainsi que de litiges juridiques liés à la politique et à des actes humanitaires.

Le thème central de ces histoires est celui des mouvements de protestware open source, nés de divers enjeux liés à la pérennité de l’open source, au changement climatique et à la liberté des logiciels open source.

Une autre histoire intéressante de protestware sur npm concerne un mainteneur du package npm node-ipc qui a décidé d’agir en réaction à une crise politique.

La bibliothèque JavaScript left-pad et Azer Koçulu, mainteneur npm

Cette histoire raconte comment des actions en justice intentées par une entreprise contre un développeur open source ont entraîné la rupture de milliers de projets de l’écosystème JavaScript, dont Node.js et Babel. €‹ €‹

Azer Koçulu, mainteneur du package npm left-pad, maintenait également un autre module npm appelé Kik. Apparemment, le module Kik a attiré l’attention des avocats d’une entreprise en raison d’une application de messagerie instantanée portant le même nom. Malgré les échanges avec les avocats et les demandes de npm, Azer a refusé de renommer le package.

Face à la menace d’un procès (et comme l’organisation npm n’avait pas réussi à trouver un accord entre les deux parties), Azer a dépublié plus de 250 de ses packages npm du registre npm, en signe de protestation.

Malheureusement, left-pad faisait partie de ces packages npm. Qu’est-ce que left-pad ? Left-pad est une toute petite bibliothèque : 17 lignes de code pour compléter des chaînes de caractères avec des espaces, si l’on se réfère à left-pad@1.0.0. Mais même cette opération nécessite de gérer certains cas particuliers. Sa dernière version, 1.3.0, a été publiée le 9 avril 2018 comme suit :

/* This program is free software. It comes without any warranty, to
     * the extent permitted by applicable law. You can redistribute it     * and/or modify it under the terms of the Do What The Fuck You Want
     * To Public License, Version 2, as published by Sam Hocevar. See
     * http://www.wtfpl.net/ for more details. */'use strict';
module.exports = leftPad;

var cache = [
  '',
  ' ',
  '  ',
  '   ',
  '    ',
  '     ',
  '      ',
  '       ',
  '        ',
  '         '
];

function leftPad (str, len, ch) {
  // convert `str` to a `string`
  str = str + '';
  // `len` is the `pad`'s length now
  len = len - str.length;
  // doesn't need to pad
  if (len <= 0) return str;
  // `ch` defaults to `' '`
  if (!ch && ch !== 0) ch = ' ';
  // convert `ch` to a `string` cuz it could be a number
  ch = ch + '';
  // cache common use cases
  if (ch === ' ' && len < 10) return cache[len] + str;
  // `pad` starts with an empty string
  var pad = '';
  // loop
  while (true) {
    // add `ch` to `pad` if `len` is odd
    if (len & 1) pad += ch;
    // divide `len` by 2, ditch the remainder
    len >>= 1;
    // "double" the `ch` so this operation count grows logarithmically on `len`
    // each time `ch` is "doubled", the `len` would need to be "doubled" too
    // similar to finding a value in binary search tree, hence O(log(n))
    if (len) ch += ch;
    // `len` is 0, exit the loop
    else break;
  }
  // pad `str`!
  return pad + str;
}

Left-pad enregistrait plus de 2,5 millions de téléchargements par mois, ce qui en faisait un outil très populaire. Sa suppression a provoqué la défaillance d’autres projets qui en dépendaient : Node.js, Babel et d’autres (plus d’informations ici : http://left-pad.io/).

Les répercussions de la suppression de dépendances dans la communauté npm ont constitué un précédent dans le registre npm. Personne ne pensait que quelqu’un ferait une chose pareille.

C’est ainsi qu’est née l’histoire d’un développeur qui a fait tomber tout l’écosystème JavaScript avec 17 lignes de code.

Comment compléter une chaîne par la gauche en JavaScript ?

Le prototype String comprend les méthodes padStart() et padEnd(), qui prennent deux arguments : la longueur en caractères à compléter et la chaîne utilisée pour la compléter. La valeur renvoyée est la nouvelle chaîne complétée. Cette API est disponible depuis Node.js 8 et est prise en charge par tous les navigateurs modernes à ce jour.

Voici un exemple de code pour compléter une chaîne par la gauche en JavaScript :

const someString = ‘h’;
console.log(someString.padStart(5, 'h'));

// output will be:
####

Beaucoup attribuent l’ajout de cette nouvelle spécification ECMAScript au package npm left-pad, qui a lancé le débat sur l’enrichissement de l’API du langage.

La bibliothèque Faker pour PHP, Laravel et d’autres projets de génération de données fictives

Seriez-vous prêt à abandonner un projet couronné de succès si cela vous permettait de réduire votre empreinte environnementale ? L’histoire qui suit est celle d’un mainteneur assez courageux pour mettre son succès de côté afin de contribuer à une planète plus verte.

Voici François. En 2011, François Zaninotto a publié Faker, une bibliothèque PHP permettant de créer des données fictives, utiles pour remplir des bases de données et effectuer des tests.

Faker a grandi au fil du temps et est devenu très populaire, avec des SDK dans d’autres langages (comme Python) et la prise en charge de plus de 70 paramètres régionaux. Mais Faker est une bibliothèque monolithique : même si vous n’avez besoin que d’un jeu de données partiel pour générer de faux noms d’utilisateur dans vos tests, vous devez tout de même télécharger l’ensemble des données, soit 3 Mo.

Pourtant, la plupart des utilisateurs n’emploient qu’un seul paramètre régional. Quelle était la taille de la bibliothèque ? Faker pesait environ 3 Mo. Pour une bibliothèque d’outillage de développement, ce n’est peut-être pas léger, sans être énorme non plus (pensez à Chrome pour les tests de bout en bout, etc.). Sauf qu’en 2019, Faker était si populaire qu’il avait été téléchargé plus de 121 millions de fois au total.

Laissez-moi vous poser une question : à quelle fréquence vous souciez-vous de la taille d’une bibliothèque (hormis les optimisations évidentes des performances côté front-end) ? Au fil des ans, Faker a probablement émis plus de 11 tonnes d’équivalent CO2.

François ne voulait pas avoir cela sur la conscience, alors le projet est désormais abandonné. Mais il aurait pu le confier à quelqu’un d’autre, non ? François avait vécu une mauvaise expérience avec une bibliothèque qu’il avait créée auparavant : Properl, une bibliothèque ORM PHP. Cela ne s’était pas bien passé pour lui.

Voilà pour la bibliothèque PHP Faker. Le dépôt du projet sur GitHub a été archivé. Plus aucune nouvelle version. Plus de nouvelles pull requests. Cela dit, comme c’est le cas avec l’open source, il est possible de forker le code source d’un projet. Des développeurs ont proposé de transférer Faker vers une nouvelle organisation avec de nouveaux mainteneurs, mais cela aurait signifié perdre la réputation acquise par le projet open source (par exemple, en supprimant le nombre d’étoiles sur GitHub). Cette solution n’a donc pas abouti.

François a laissé une dernière note aux nouveaux mainteneurs et développeurs : « Si cela vous intéresse, vous pouvez commencer par forker Faker. Ce sera bien mieux que Faker. Sachez simplement que vous le regretterez probablement dans quelques années ;) ».

La bibliothèque npm Faker

Cette bibliothèque Faker.js permet également de générer une grande quantité de données aléatoires à utiliser dans vos tests, mais son histoire est très différente de celle de la bibliothèque PHP évoquée précédemment.

« Le travail gratuit, c’est terminé », a déclaré Marak Squires dans un ticket GitHub de l’un de ses dépôts, en novembre 2020.

La maintenance des logiciels open source représente une lourde charge. Elle va du codage à la maintenance régulière du projet (documentation comprise), en passant par la publication de versions, la mise à jour des fichiers de journal des modifications, la création d’un environnement accueillant pour les nouveaux développeurs et contributeurs qui souhaitent rejoindre le projet, les réponses aux questions, l’analyse des problèmes signalés et la revue des pull requests. Ce ne sont là que quelques-unes des tâches nécessaires pour maintenir un projet open source en bonne santé.

Beaucoup d’entre nous, développeurs comme entreprises à but lucratif, utilisent énormément de logiciels open source. Mais contribuons-nous en retour ?

Marak est un développeur open source qui maintient plusieurs projets open source. Il maintient un package npm open source populaire appelé faker.js, qui a, à une période, enregistré plus de douze millions de téléchargements par mois. Ne le confondez pas avec l’histoire précédente de la bibliothèque PHP Faker. Il s’agit de projets, de mainteneurs et d’histoires différents.

Le travail de Marak aidait les développeurs de grandes entreprises du Fortune 500 et, au bout du compte, contribuait à la croissance de ces entreprises. Mais, comme beaucoup de mainteneurs, il n’en tirait pas grand-chose. Le travail des mainteneurs est largement dépourvu de financement et de reconnaissance.

En novembre 2020, Marak a décidé de prendre position sur la pérennité de l’open source, ou plutôt sur son absence. Le mainteneur a ouvert un ticket dans son dépôt GitHub pour annoncer qu’il ne fournirait plus de travail gratuit.

Issue GitHub intitulée « No more free work from Marak – Pay Me or Fork This #1046 », avec une scène de manifestation de Futurama dans le commentaire.

À en juger par les réactions emoji à la déclaration de Marak dans ce ticket GitHub, la communauté l’a largement acceptée et reconnue. Marak a été entendu, mais ses actions n’ont pas laissé de trace notable et durable.

Le 5 janvier 2022, le mainteneur a publié une nouvelle version du package npm Faker.js, portant le numéro de version sémantique 6.6.6, de sorte que faker@6.6.6 pouvait être téléchargé depuis le registre npm.

La nouvelle version 6.6.6 a supprimé toute trace du code source d’origine du package npm Faker.js. Toute nouvelle installation de cette nouvelle version majeure entraînerait un dysfonctionnement.

Pour accompagner la publication de cette déclaration sous la version faker@6.6.6, il a également forcé l’envoi d’un commit dans le dépôt GitHub de Faker.js, supprimant l’intégralité du code source :

Page d’un dépôt GitHub affichant les fichiers du projet et le titre d’un README : « Que s’est-il vraiment passé avec Aaron Swartz ? »
Historique des commits GitHub en thème sombre, affichant la branche master et un commit « endgame » de Marak, avec le hash 2c4f82f.

Quel impact un package npm défectueux peut-il avoir sur ses utilisateurs ? Pour l’évaluer, il faut comprendre le fonctionnement du versionnage des packages npm et celui du gestionnaire de packages npm en général.

En bref : si vous utilisez déjà faker dans vos projets, que vous ayez recours ou non à un fichier de verrouillage pour figer vos dépendances, le gestionnaire de packages npm récupérera la dernière version en fonction de la résolution des versions mineures ou de correctifs. Vous resterez toutefois dans la « zone sûre » de la version majeure actuelle de Faker.js que vous utilisez. En effet, faker@5.5.3 est la dernière version majeure sûre, et le passage à la version majeure défectueuse faker@6.6.6 nécessite une mise à niveau explicite, qui n’est souvent pas proposée automatiquement à l’utilisateur final.

Ce mainteneur cherchait peut-être à faire passer un message, mais personne n’en a réellement subi les conséquences ? L’histoire continue : Marak a intégré une vulnérabilité par déni de service dans le package npm colors, touchant environ cent millions de téléchargements mensuels.

Bonnes pratiques pour utiliser les bibliothèques open source de manière responsable

Voici quatre recommandations pratiques pour gérer les logiciels open source et éviter les risques de sécurité liés aux packages npm de type protestware et aux logiciels sans maintenance.

1. Gérez efficacement votre infrastructure de bibliothèques open source

Que faire, en tant que développeurs dépendant de la disponibilité des bibliothèques open source ? Réinstaller les packages à partir des registres est une méthode inefficace et lente, qui peut produire des résultats non déterministes.

Pour mieux faire face aux situations où des packages et bibliothèques open source deviennent obsolètes ou sont supprimés de registres publics tels que npm, PyPI et d’autres, nous vous recommandons d’utiliser des proxys privés locaux avec mise en cache, comme le projet open source Verdaccio. Nous avons interrogé Juan Picado, mainteneur de Verdaccio. Lisez l’entretien pour en savoir plus sur la gestion de vos bibliothèques open source.

2. Évaluez les bibliothèques open source

Lorsque vous adoptez de nouveaux packages open source ou envisagez des alternatives à ceux que vous utilisez déjà, prenez le temps d’évaluer la communauté autour du projet, son historique de maintenance et son activité actuelle, ainsi que son niveau de sécurité. D’autres aspects comptent également, notamment la qualité du projet, la présence de tests et la disponibilité de documentation.

Snyk Advisor est un outil gratuit qui aide les développeurs à évaluer la qualité des packages npm en quantifiant différents aspects d’un package open source. Par exemple, Snyk Advisor attribue un score de santé au package npm nodemon.

Page npm de nodemon v2.0.7 affichant un score de santé du package de 90/100, des packages similaires, le nombre de téléchargements, la fréquence des commits et des indicateurs sur le projet

3. Utilisez un fichier de verrouillage pour figer les dépendances

Utiliser un fichier de verrouillage pour figer les dépendances sur des versions connues et testées est un excellent moyen d’obtenir des installations déterministes. Cela vaut quel que soit l’écosystème JavaScript : c’est une méthode éprouvée pour éviter les mauvaises surprises dans l’intégration continue et ailleurs.

Si vous commencez à utiliser des fichiers de verrouillage et que vous ne savez pas bien comment ils fonctionnent, je vous recommande de lire Qu’est-ce qu’un fichier package-lock.json ? pour comprendre les principes et les mécanismes de la gestion des dépendances.

Schéma du fonctionnement de npmFaker : le fichier package-lock.json d’un projet npm sert à installer les dépendances, tandis que le fichier yarn.lock est conservé pour les contributeurs.

4. Figez les dépendances transitives

Dans certaines situations, vous ne pouvez pas contrôler la version des dépendances transitives ajoutées à votre arborescence node_modules. Cela s’explique par le fait que ces dépendances font partie d’autres dépendances déclarées par d’autres mainteneurs.

Cela dit, les gestionnaires de packages npm et d’autres, comme yarn ou pnpm, permettent de remplacer la version d’une dépendance imbriquée en déclarant la plage de versions acceptables dans votre fichier package.json.

Voici un exemple qui s’est révélé essentiel après les répercussions du sabordage du module peacenotwar et du protestware du package npm node-ipc :

"overrides": {
    "node-ipc@>9.2.1 <10": "9.2.1",
    "node-ipc@>10.1.0": "10.1.0
  }

Pour conclure

La sécurité des logiciels open source et l’activisme sont des sujets qui me tiennent à cœur. Cet article s’appuie sur une présentation que j’ai donnée à Cloud Native SecurityCon à Valence, en mai 2022. Si le sujet vous intéresse, vous pouvez regarder l’enregistrement ici :

The Unexpected Demise of Open Source Libraries - Liran Tal, Synk

Je vous recommande également vivement d’adopter une approche proactive de la sécurité de vos dépendances open source en connectant vos dépôts Git à Snyk afin de bénéficier de correctifs de sécurité automatisés et de mises à niveau des versions de vos dépendances.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis de capture du drapeau en regardant à la demande notre atelier virtuel d’initiation.

Lire la suite

feature insights context
Blog

Les attaques autonomes sont déjà là. La défense doit suivre leur rythme.

Les attaquants autonomes réduisent la fenêtre de défense. Découvrez comment la découverte, la correction, la validation et la prévention continues peuvent aider les équipes de sécurité à suivre le rythme.

feature insights context
Blog

La prévention est-elle essentiellement un problème résolu ?

La prévention dans le code généré par les agents est résolue sur le plan architectural, mais le défi reste de choisir des contrôles qui protègent la sécurité sans ralentir le développement.

Live Stream

Les agents de remédiation démystifiés : pourquoi corriger vaut mieux que détecter

Découvrez comment l’agent de remédiation de Snyk utilise les renseignements de sécurité, l’analyse de la cassabilité et la validation pour transformer les vulnérabilités en pull requests prêtes à être fusionnées.