El paquete npm faker y el inesperado declive de las bibliotecas de código abierto
2 de septiembre de 2022
0 minutos de lectura¿Adónde van a morir las dependencias de código abierto y por qué llegan a su fin? ¿Qué pasó con el módulo npm faker? ¿Puede volver a pasar? Acompáñame para descubrir cómo las bibliotecas de software de código abierto alcanzan la gloria y cómo llegan al final de su vida útil. También compartiré algunas conclusiones para desarrolladores e ingenieros de operaciones.
Quiero compartir varias historias de los ecosistemas de JavaScript y PHP sobre interrupciones repentinas de la cadena de suministro de software por inquietudes climáticas y ambientales, así como disputas legales relacionadas con la política y acciones humanitarias.
La biblioteca JavaScript left-pad y Azer Koçulu, mantenedor de npm
La biblioteca Faker para PHP, Laravel y otros proyectos que generan datos ficticios
El tema central de estas historias son los movimientos de protestware de código abierto, que surgieron a raíz de diversos problemas relacionados con la sostenibilidad del código abierto, el cambio climático y la libertad del software de código abierto.
Otra historia interesante sobre protestware en npm se centra en un mantenedor del paquete npm node-ipc que tomó medidas ante una crisis política.
La biblioteca JavaScript left-pad y Azer Koçulu, mantenedor de npm
Esta es la historia de cómo las acciones legales emprendidas por una entidad comercial contra un desarrollador de código abierto provocaron la interrupción de miles de proyectos del ecosistema JavaScript, entre ellos Node.js y Babel.
Azer Koçulu, mantenedor del paquete npm left-pad, también mantenía otro módulo npm llamado Kik. Al parecer, el módulo Kik llamó la atención de algunos abogados corporativos debido a una aplicación de mensajería instantánea con el mismo nombre. A pesar de las comunicaciones de los abogados y las solicitudes de npm, Azer se negó a cambiar el nombre del paquete.
Ante la amenaza de una demanda (y como la organización npm no pudo lograr un acuerdo entre ambas partes), Azer retiró del registro npm más de 250 de sus paquetes como protesta.
Lamentablemente, uno de esos paquetes npm era left-pad. ¿Qué es left-pad? Left-pad es una pequeña biblioteca de 17 líneas de código que agrega espacios al inicio de cadenas de texto, si tomamos como referencia left-pad@1.0.0. Pero incluso agregar espacios al inicio de una cadena requiere manejar algunos casos límite. Su versión más reciente, la 1.3.0, se publicó el 9 de abril de 2018 de la siguiente manera:
Left-pad recibía más de 2.5 millones de descargas al mes, lo que lo hacía muy popular. Su retirada provocó fallas en otros proyectos que dependían de él: Node.js, Babel y otros (más información: http://left-pad.io/).
Las consecuencias de retirar dependencias en la comunidad npm sentaron un precedente en el registro de npm. Nadie pensaba que alguien haría algo así.
Esta historia pasó a conocerse como la de un desarrollador que rompió todo el ecosistema JavaScript con 17 líneas de código.
¿Cómo agregar espacios al inicio de una cadena en JavaScript?
El prototipo String incluye los métodos padStart() y padEnd(), que reciben dos argumentos: la cantidad de caracteres que se deben agregar y la cadena con la que se deben agregar. El valor devuelto es la nueva cadena con el relleno. Esta API está disponible desde Node.js 8 y, actualmente, es compatible con todos los navegadores modernos.
A continuación, se muestra un ejemplo de código para agregar espacios al inicio de una cadena en JavaScript:
Muchos atribuirían la incorporación de esta nueva especificación de ECMAScript al paquete npm left-pad, que impulsó el debate sobre una API de lenguaje más completa.
La biblioteca Faker para PHP, Laravel y otros proyectos que generan datos ficticios
¿Podrías renunciar a un proyecto exitoso si eso significara reducir tu impacto ambiental? La siguiente historia trata de un mantenedor que tuvo el valor de dejar de lado su éxito para contribuir a un planeta más verde.
Conoce a François. En 2011, François Zaninotto lanzó Faker, una biblioteca de PHP para crear datos ficticios, útil para poblar bases de datos y realizar pruebas.
Con el tiempo, Faker creció y se volvió muy popular, con SDK en otros lenguajes (como Python) y compatibilidad con más de 70 configuraciones regionales. Pero Faker es una biblioteca monolítica: aunque solo necesites un conjunto parcial de datos para generar nombres de usuario ficticios en tus pruebas, debes descargar el conjunto de datos completo, que ocupa 3 MB.
Sin embargo, la mayoría de las personas solo usa una configuración regional. ¿Cuánto ocupaba la biblioteca? La biblioteca Faker ocupaba unos 3 MB. Para una herramienta de desarrollo, quizá no sea poco, pero tampoco es demasiado (por ejemplo, Chrome para pruebas de extremo a extremo). Salvo que, para 2019, Faker se había vuelto tan popular que acumulaba más de 121 millones de descargas.
Déjame preguntarte algo: ¿con qué frecuencia has considerado el tamaño de una biblioteca como un problema (aparte de las optimizaciones evidentes de rendimiento del frontend)? A lo largo de los años, probablemente Faker haya emitido más de 11 toneladas métricas de CO2 equivalente.
François no quería cargar con eso en su conciencia, así que el proyecto ya no se mantiene. Pero podría haberlo dejado en manos de otra persona, ¿verdad? François había tenido una mala experiencia con una biblioteca que creó anteriormente: Properl, una biblioteca ORM para PHP. No le fue bien.
Eso resume la historia de la biblioteca Faker para PHP. El repositorio del proyecto en GitHub se archivó. No habrá nuevas versiones ni nuevos pull requests. Dicho esto, como ocurre con el código abierto, es posible crear una bifurcación del código fuente de un proyecto. Algunos desarrolladores ofrecieron trasladar Faker a una nueva organización con nuevos mantenedores, pero eso implicaba perder la reputación de código abierto del proyecto (por ejemplo, al eliminar las estrellas de GitHub). Así que la propuesta no prosperó.
François dejó una nota final para los nuevos mantenedores y desarrolladores: «Si te interesa, puedes empezar por crear una bifurcación de Faker. Será mucho mejor que Faker. Solo ten en cuenta que probablemente te arrepentirás dentro de unos años ;)».
La biblioteca npm Faker
Esta biblioteca Faker.js también ayuda a generar grandes cantidades de datos aleatorios que puedes usar en tus pruebas, pero su historia es muy distinta de la de la biblioteca PHP.
«No más trabajo gratis», escribió Marak Squires en un problema de GitHub de uno de sus repositorios en noviembre de 2020.
Mantener software de código abierto es una gran carga. El trabajo abarca desde programar hasta realizar el mantenimiento habitual del proyecto (incluida la documentación), publicar versiones, actualizar los archivos de cambios, crear un entorno acogedor para los nuevos desarrolladores y colaboradores que quieran sumarse al proyecto, responder preguntas, investigar los problemas reportados y revisar pull requests. Estas son solo algunas de las tareas necesarias para mantener un proyecto de código abierto saludable.
Sin duda, muchos desarrolladores y empresas con fines de lucro usamos mucho software de código abierto. Pero ¿contribuimos algo a cambio?
Marak es un desarrollador de código abierto y mantenedor de varios proyectos de este tipo. Mantiene un popular paquete npm de código abierto llamado faker.js, que en su momento llegó a recibir más de doce millones de descargas al mes. No lo confundas con la historia anterior de la biblioteca Faker para PHP: son proyectos, mantenedores e historias diferentes.
El trabajo de Marak ayudaba a desarrolladores de empresas Fortune 500 y, en última instancia, al crecimiento de esas empresas. Pero, como muchos mantenedores, no recibía mucho a cambio. El trabajo de quienes mantienen proyectos suele carecer de financiamiento y reconocimiento.
En noviembre de 2020, Marak decidió hacer una declaración sobre la sostenibilidad del código abierto, o la falta de ella. El mantenedor abrió un problema en su repositorio de GitHub para anunciar que ya no haría más trabajo gratis.

A juzgar por las reacciones con emojis a la declaración de Marak en este problema de GitHub, la comunidad la aceptó y reconoció ampliamente. Marak se hizo escuchar, pero sus acciones no dejaron una impresión duradera.
El 5 de enero de 2022, el mantenedor publicó una nueva versión del paquete npm Faker.js con el número de versión semántica 6.6.6, por lo que faker@6.6.6 era una versión válida disponible para descargar desde el registro de npm.
La nueva versión 6.6.6 eliminó por completo todos los rastros del código fuente original del paquete npm Faker.js. Las nuevas instalaciones de esta versión principal dejaban de funcionar correctamente.
Junto con la publicación de la nueva versión faker@6.6.6, también hicieron un push forzado de un commit al repositorio de Faker.js en GitHub que eliminó todo el código fuente:


¿Qué impacto tendría un paquete npm dañado en quienes lo usan? Para evaluarlo, primero debes entender cómo funciona el versionado de paquetes npm y cómo suele funcionar el administrador de paquetes npm.
En resumen: si ya usas faker en tus proyectos, el administrador de paquetes npm buscará la versión más reciente según las resoluciones de versión minor o patch, tanto si usas un archivo de bloqueo para fijar tus dependencias como si no. Sin embargo, seguirás dentro de la «zona segura» de la versión principal de Faker.js que ya tienes. Esto se debe a que faker@5.5.3 es la versión principal segura más reciente, y la versión principal dañada faker@6.6.6 requiere una actualización explícita que, por lo general, no se ofrece automáticamente al usuario final.
Entonces, ¿quizá este mantenedor estaba haciendo una declaración, pero nadie sintió realmente las consecuencias? La historia continúa: Marak agregó una vulnerabilidad de denegación de servicio integrada en el paquete npm colors, que afectó a unos cien millones de descargas mensuales.
Recomendaciones para usar bibliotecas de código abierto de forma responsable
A continuación, encontrarás cuatro recomendaciones prácticas para administrar software de código abierto y evitar el impacto de seguridad de los paquetes npm de protestware y del software sin mantenimiento.
1. Administra de forma eficiente la infraestructura de tus bibliotecas de código abierto
¿Qué podemos hacer como desarrolladores que dependemos de la disponibilidad de las bibliotecas de código abierto? Volver a instalar paquetes desde los registros es ineficiente y lento, y puede generar resultados no deterministas.
Para manejar mejor las situaciones en las que los paquetes y las bibliotecas de código abierto quedan obsoletos y se eliminan de registros abiertos como npm, PyPI y otros, recomendamos usar proxies privados locales y de caché, como el proyecto de código abierto Verdaccio. Entrevistamos a Juan Picado, mantenedor de Verdaccio. Lee la entrevista para conocer más sobre cómo administrar tus bibliotecas de código abierto.
2. Evalúa las bibliotecas de código abierto
Al adoptar nuevos paquetes de código abierto o considerar alternativas a los que ya usas, dedica tiempo a evaluar la comunidad que rodea al proyecto, su historial de mantenimiento y su actividad actual, así como su nivel de seguridad. También son importantes otros aspectos, como la calidad del proyecto y si cuenta con pruebas y documentación disponible.
Una herramienta que ayuda a los desarrolladores a evaluar la calidad de los paquetes npm es Snyk Advisor, un recurso gratuito que permite cuantificar distintos aspectos de un paquete de código abierto. Por ejemplo, Snyk Advisor ofrece una puntuación de estado para el paquete npm nodemon.

3. Usa un archivo de bloqueo para fijar las dependencias
Usar un archivo de bloqueo para fijar las dependencias en versiones conocidas y probadas es una excelente manera de lograr instalaciones deterministas. Esto aplica a todo el ecosistema JavaScript y es una técnica conocida para evitar sorpresas en CI y otros entornos.
Si recién empiezas a usar archivos de bloqueo y no sabes bien cómo funcionan, te recomiendo leer Qué es un package-lock.json para comprender la semántica y los mecanismos de la administración de dependencias.

4. Fija las dependencias transitivas
En ciertas situaciones, quizá no puedas controlar la versión de las dependencias transitivas agregadas a tu árbol node_modules. Esto sucede porque esas dependencias forman parte de otras dependencias declaradas por otros mantenedores.
Dicho esto, los administradores de paquetes npm y otros, como yarn o pnpm, incluyen una forma de reemplazar la versión de una dependencia anidada al declarar el rango de versiones aceptables en tu archivo package.json.
Este es un ejemplo que fue de vital importancia debido a las repercusiones del sabotaje del módulo peacenotwar y el protestware del paquete npm node-ipc:
Palabras finales
La seguridad del software de código abierto y el activismo son temas que me apasionan. Esta publicación se basa en una charla que di en Cloud Native SecurityCon, en Valencia, en mayo de 2022. Si te interesa, puedes ver la grabación aquí:

También recomiendo encarecidamente adoptar un enfoque proactivo para proteger las dependencias de código abierto: conecta tus repositorios de Git a Snyk para recibir correcciones de seguridad automatizadas y actualizaciones de versiones de dependencias.
Empieza con los desafíos de Capture the Flag
Aprende a resolver desafíos de captura la bandera con nuestro taller virtual introductorio a pedido.


