• pnpm
  • seguridad
  • dependencias
  • npm
  • yarn

Actualiza dependencias transitivas con PNPM: Soluciona las vulnerabilidades de seguridad sin romper nada

Solucionar vulnerabilidades de seguridad puede ser una tarea frustrante, especialmente cuando involucra dependencias transitivas. Aprende cómo actualizarlas sin afectar tus dependencias directas.

Gao
Gao
Founder

Hoy en día, las vulnerabilidades de seguridad son un problema común en el desarrollo de software. Afortunadamente, tenemos herramientas como GitHub Dependabot que nos ayudan a mantener nuestras dependencias actualizadas con detección automática y solicitudes de extracción.

Dependabot

Sin embargo, no siempre funciona como se espera. Dado que algunas dependencias son transitivas, actualizarlas puede ser una tarea difícil para estas herramientas, ya que no conocen el impacto de los cambios y qué decisión tomar cuando hay conflictos. Necesitamos manejar estos casos manualmente.

Métodos que no funcionan

  • Comandos oficiales como pnpm up desordenarán tu archivo pnpm-lock.yaml. Hay un problema sobre esto que sigue abierto al momento de escribir.
  • Instalar la última versión de la dependencia directa que tiene la dependencia transitiva objetivo puede no funcionar. Si la dependencia directa no actualizó las definiciones de la versión, la dependencia transitiva no se actualizará, ya que ha sido resuelta y bloqueada en el archivo pnpm-lock.yaml.

La solución

El campo overrides es una característica poderosa en PNPM que te permite sobrescribir algunas resoluciones de versión. Usaremos esta función para actualizar dependencias transitivas y hacer el cambio lo más mínimo posible.

Usemos la alerta anterior de Dependabot como ejemplo. Nos dice que el paquete follow-redirects tiene una vulnerabilidad de seguridad, y la versión corregida es 1.15.6. Sin embargo, la dependencia directa gatsby usa axios, que depende de [email protected].

Paso 1: Encuentra la dependencia transitiva

Hay muchas maneras de localizar la dependencia transitiva, pero te recomendaría la forma más sencilla: buscar en el archivo pnpm-lock.yaml.

¿Qué tal "pnpm why"?

El comando pnpm why <package> es útil, de hecho. Sin embargo, puede confundirte en este caso. Por ejemplo, cuando ejecuto pnpm why follow-redirects, aquí hay una parte de la salida:

En realidad, solo existe una resolución para follow-redirects en el archivo pnpm-lock.yaml. El comando pnpm why puede mostrarte múltiples rutas que dependen de la misma versión del paquete.

Paso 2: Añadir los overrides

El caso más fácil es cuando solo existe una resolución en el archivo pnpm-lock.yaml. Puedes añadir el override directamente en el archivo package.json:

Si estás en un workspace, deberías añadir el override al archivo package.json en la raíz del workspace.

Paso 3: Aplica los cambios

Ejecuta pnpm install para aplicar los cambios. Podemos ver que el paquete follow-redirects se actualiza a 1.15.6 en el archivo pnpm-lock.yaml con cambios mínimos.

Ahora puedes eliminar el campo overrides del archivo package.json para mantenerlo limpio. Luego ejecuta pnpm install nuevamente para validar que los cambios se pueden aplicar sin el campo overrides.

Solución de problemas

Los pasos anteriores son el caso ideal. Las cosas pueden no salir siempre como se espera. Aquí hay algunos consejos para solucionar problemas:

La versión es revertida después de eliminar el campo "overrides"

Esto puede suceder cuando el paquete dependiente tiene una versión fija o un rango que no incluye la versión objetivo. Revisa el archivo package.json del paquete dependiente, en este caso, axios, para ver si esto aplica.

Si es así, necesitas mantener el campo overrides en el archivo package.json hasta que el paquete dependiente actualice las definiciones de la versión.

Hay múltiples resoluciones para la dependencia transitiva

A medida que el proyecto crece, el archivo pnpm-lock.yaml puede inflarse con múltiples resoluciones para el mismo paquete. Por ejemplo, puede haber dos versiones principales del mismo paquete foo:

El informe de vulnerabilidad muestra que [email protected] tiene un problema de seguridad que se soluciona en 1.0.1, y [email protected] no se ve afectado. No podríamos simplemente añadir un override a foo:

  • Si añadimos un override "foo": "^1.0.1", el [email protected] se degradará a 1.0.1. Esto puede romper el proyecto, ya que [email protected] puede tener algunas características nuevas que son utilizadas en los paquetes dependientes.
  • Si añadimos un override "foo": "^2.0.0", el [email protected] se actualizará a 2.0.0. Esto puede romper el proyecto, ya que [email protected] puede tener algunos cambios que no son compatibles.

Suponiendo que foo sigue Semantic Versioning, podemos añadir un override como este:

Esto solo actualizará [email protected] a 1.0.1 y mantendrá [email protected] sin cambios.

Conclusión

Antes de que PNPM soporte la actualización directa de dependencias transitivas, el campo overrides es una buena solución para arreglar vulnerabilidades de seguridad sin romper nada. Espero que este artículo te ayude a manejar estos casos más eficientemente. En Logto, usamos este método para mantener nuestras dependencias actualizadas y seguras.