Utilizado para automatizar la instalación, actualización y configuración de paquetes, el administrador npm está en riesgo. De hecho, este último presenta un error de diseño que los atacantes podrían aprovechar para ocultar dependencias y scripts maliciosos dentro de sus paquetes. El problema, llamado "confusión manifiesta", surge de la falta de coherencia entre los archivos de manifiesto que acompañan a los paquetes archivados y el archivo de metadatos json incluido en el propio paquete. El error fue revelado públicamente esta semana por Darcy Clarke, ex líder de ingeniería del equipo de CLI de npm. Este último abandonó GitHub, propietario de npm, en diciembre de 2022, pero dijo que la empresa estaba al tanto de este problema desde noviembre pasado y que lo notificó nuevamente en marzo de 2023. Después de una investigación independiente, se llegó a la conclusión de que el impacto era mayor de lo que se pensaba originalmente.

Según Darcy Clarke, la comunidad generalmente asume que los manifiestos publicados con un paquete en el registro npm coinciden con el contenido del archivo de metadatos package.json incluido en el paquete, el tarball descargado del repositorio. Este no es el caso y los administradores de paquetes JavaScript del lado del cliente, como npm, pero también las herramientas de seguridad que escanean paquetes desde los repositorios npm, no validan adecuadamente estos archivos entre sí. Esto significa que los paquetes pueden tener dependencias ocultas o scripts de instalación enumerados en sus archivos package.json pero no en el archivo de manifiesto separado. Estas dependencias y scripts serán analizados y ejecutados por clientes de JavaScript, como la interfaz de línea de comandos (CLI) de npm y otros, incluso si no figuran en el manifiesto del paquete. "Hay varias formas en que este error afecta a los consumidores/usuarios finales: envenenamiento de la caché (es decir, el paquete guardado puede no coincidir con el nombre y la especificación de versión de ese paquete en el registro/URI), instalación de dependencias desconocidas/no listadas (engañando a las herramientas de seguridad/auditoría) ; ejecutar scripts desconocidos/no listados (engañando a las herramientas de seguridad/auditoría); posible ataque de degradación (donde la especificación de la versión guardada en los proyectos coincide con una versión vulnerable no especificada del paquete)”, dijo Clarke.

Índice
  1. Validación en manos de instaladores de paquetes.
  2. Yarn y pnpm también son vulnerables
  3. No hay una solución fácil para la vulnerabilidad de confusión manifiesta

Validación en manos de instaladores de paquetes.

En esencia, este problema se debe al hecho de que no existe una "fuente canónica de verdad" clara para los metadatos de un paquete, como nombre, versión, dependencias, scripts, licencia, etc. Estos elementos se especifican en el archivo package.json que se incluye en el propio archivo del paquete y que admite valores de verificación de integridad, como hashes criptográficos. Sin embargo, algunos de estos datos pueden especificarse en el archivo de manifiesto del paquete cuando se publica en el registro npm y este manifiesto dicta qué información mostrará el registro. Por ejemplo, Darcy Clarke creó un paquete de muestra cuyo archivo package.json enumera otro paquete como dependencia, pero cuando lo publicó, no incluyó la dependencia en el manifiesto. Como resultado, la entrada del paquete en el repositorio npm.js enumera el paquete con 0 dependencias, porque el registro utiliza el manifiesto como única fuente de verdad.

Sin embargo, el registro en sí solo valida la información en el paquete.json que coincide con la del manifiesto. Esta tarea se deja al cliente que instala el paquete. Pero resulta que tampoco hacen esta validación... Por ejemplo, la versión 6 de npm (npm@6), viene con la versión 14 del tiempo de ejecución de node.js (soporte a largo plazo), ejecutará un script de instalación definido en el archivo package.json incluso si el script no está definido en el manifiesto. Por lo tanto, una dependencia incluida en package.json y ausente en el manifiesto no se implementará durante la primera descarga e instalación del paquete. Sin embargo, si esto se almacena en caché localmente y luego se instala desde una fuente local con las opciones de línea de comando -prefer-offline y -no-package-lock, se instalarán las dependencias ocultas en el archivo package.json. Npm versión 9 (npm@9), la versión estable actual de npm, instalará de manera similar las dependencias a las que se hace referencia en el paquete.json de un paquete almacenado en caché cuando se utiliza la configuración sin conexión.

Yarn y pnpm también son vulnerables

Los administradores de paquetes Yarn y pnpm, que son alternativas a npm, también son vulnerables y ejecutarán scripts a los que se hace referencia en el archivo package.json que faltan en el manifiesto. Yarn también preferirá la versión del paquete definida en package.json a esta. Como estos dos valores pueden ser diferentes, esto abre la puerta a un ataque de degradación. Son peligrosos porque un paquete puede ser reemplazado por una versión anterior que tiene una vulnerabilidad conocida. No faltan iteraciones de este tipo defectuosas, incluso en proyectos mantenidos activamente. La semana pasada, investigadores de Snyk y Redhunt Labs publicó los resultados de un proyecto de investigación el cual consistió en analizar más de 11.000 repositorios pertenecientes a las 1.000 principales empresas en GitHub. El análisis buscó fallas en las dependencias enumeradas en estos proyectos que abarcan múltiples lenguajes de programación. Para JavaScript (npm e hilo), el equipo extrajo 1,9 millones de dependencias e identificó aproximadamente 550.000 casos de agujeros de seguridad conocidos.

Darcy Clarke cree que este problema se divide en diferentes categorías de defectos. Señala que "hay un historial que depende en gran medida del cliente (también conocido como npm CLI) para realizar el trabajo que se debe realizar en el lado del servidor". Además de estos administradores de paquetes del lado del cliente, el problema también afecta a otras herramientas y registros de paquetes de terceros, incluidos los centrados en la seguridad: Snyk, Chinese NPM Mirror, CloudFlare npm CDN Mirror, UNPKG CDN Mirror, Skypack, JSPM e incluso repositorios locales. creado con Artifactory de jFrog.

No hay una solución fácil para la vulnerabilidad de confusión manifiesta

Solucionar este problema y aplicar repentinamente la confirmación no es sencillo y puede llevar algún tiempo hasta que GitHub encuentre una solución. Porque probablemente hay muchos paquetes que tienen esta confusión y no es por motivos maliciosos. Darcy Clarke señaló que la propia API npm también causa este tipo de inconsistencias. Por ejemplo, al publicar un paquete a través de la interfaz de comando npm donde se encuentra un archivo vinculante.gyp dentro del proyecto, el cliente agregará una entrada al archivo de manifiesto llamada: scripts "node-gyp reconstruir" .install. Esta entrada no estará presente en el archivo package.json. "Es comprensible que GitHub se encuentre en una situación difícil", dijo el funcionario. “El hecho de que npmjs.com haya operado de esta manera durante más de una década significa que el estado actual está bastante codificado y es probable que penetre de manera única una defensa. Como se mencionó anteriormente, la propia API npm se basa en este comportamiento y existen otros usos potencialmente no maliciosos en la naturaleza de este comportamiento en la actualidad.

Los usuarios deben comunicarse con todos los autores conocidos de herramientas que dependen de npm y pedirles que se basen en la información del paquete.json en lugar del manifiesto, excepto la versión y el nombre, que pueden ser diferentes por razones legítimas. Otra opción sería utilizar un proxy entre el cliente y el registro que valide estrictamente los metadatos de ambas fuentes para garantizar la coherencia.