Corres npm audit, y ahí está:
14 vulnerabilities (3 low, 6 moderate, 4 high, 1 critical)
Vaya, fíjate: catorce vulnerabilidades. Probablemente se trate de un proyecto que lleva un mes sin tocarse y al que quizá hayas echado un vistazo un par de veces. Lo más probable es que ni siquiera pudieras nombrar esos paquetes si te lo preguntaran. Seguramente se han colado con alguna dependencia directa. El primer paso es ya una rutina a estas alturas: ejecuta npm audit fix, espera a que se solucionen algunos de los problemas, cierra el terminal y sigue con lo tuyo. En realidad, nadie se pone a analizar en profundidad las catorce vulnerabilidades.
¿Pereza? No. ¿Cansancio? Sí, y merece la pena mencionarlo como un problema en sí mismo, en lugar de incluirlo en la afirmación de que «a los desarrolladores no les importa la seguridad», porque ambas cosas dan lugar a soluciones muy diferentes.
El problema del ruido con npm audit
npm audit Es bueno en una cosa: avisarte de que una vulnerabilidad conocida aparece en algún punto de tu árbol de dependencias. ¿Decirte si realmente afecta a tu aplicación en ejecución? Eso ya es otra historia.
Cuando el código, oculto a cuatro niveles de profundidad, empieza a generar una clasificación de gravedad «Alta», ¿qué se supone que debes hacer al respecto? npm define la gravedad en función del impacto y la posibilidad de explotación en el caso de uso más habitual, y puede que tu aplicación no sea ese caso habitual. Por otra parte, «nunca lo llamamos» tampoco es una excusa válida, ya que los scripts de instalación y las herramientas de compilación pueden ejecutar código vulnerable antes de que una solicitud llegue siquiera a tu aplicación.
Luego está el recuento. Ese 14 corresponde al número de paquetes marcados, no a problemas distintos. Un mismo paquete puede contener varios avisos y, aun así, contar solo una vez; además, npm también marca las «metavulnerabilidades»: paquetes cuyo rango de dependencias declarado solo puede resolverse con una versión afectada de algún componente subyacente. Así pues, esas catorce «vulnerabilidades» podrían ser en realidad cuatro o cinco problemas distintos que se presentan de diferentes formas.
Y lo que es peor, las dependencias de desarrollo se señalan con exactamente la misma urgencia que el código de ejecución en producción. Un complemento de ESLint vulnerable en el portátil de un desarrollador y una biblioteca de autenticación vulnerable expuesta a la red pública de Internet no pertenecen, en esencia, a la misma categoría de emergencia. Sin embargo, esto tiene sus pros y sus contras. Una dependencia de compilación que se ejecuta en CI, maneja datos confidenciales o influye en el artefacto que se distribuye no tiene baja prioridad solo porque se encuentre bajo devDependencies.
La herramienta no está necesariamente averiada; simplemente carece del contexto de ejecución necesario para responder a la pregunta que te interesa.
Por qué los equipos pierden la motivación
Fatiga, ansiedad, nerviosismo: nada de eso es exclusivo de la supervisión de dependencias y de los canales de CVE, pero la seguridad de las dependencias es una fuente importante de estas tres sensaciones.
La pila de incidencias parece no tener fin. No dejan de acumularse más rápido de lo que nadie puede resolverlas. Cuando has evaluado tu quincuagésima vulnerabilidad y resulta que cuarenta y nueve de ellas son irrelevantes, inaccesibles o ya se han solucionado en otro lugar, la etiqueta de «alta gravedad» ya no tiene tanto peso. A eso se le llama «fatiga de alertas».
El verdadero coste no son las conversaciones ni las alertas, sino lo que queda oculto. Si todas las alertas se tratan por igual, lo mismo ocurre con la que realmente importa. Las revisiones empiezan a convertirse en un mero trámite: se ejecutan auditorías en la integración continua, alguien echa un vistazo al recuento y no se revisa nada. Al final, alguien añade || true a la fase de auditoría para que el flujo vuelva a estar en verde, y esa línea perdure más allá de que todos hayan olvidado por qué está ahí. No es que a nadie le haya dejado de importar. Es que la lista de tareas pendientes creció más rápido de lo que nadie podía ir resolviéndola.
Las mejoras también tienen su importancia. npm audit fix se limita a las actualizaciones que se ajustan a los rangos de versiones que hayas indicado. Cualquier cambio fuera de esos rangos, lo que puede incluir un cambio de versión mayor según SemVer, requiere --force, y la propia documentación de npm desaconseja utilizarlo a la ligera. Algunos problemas no tienen solución automática alguna. «Solo tienes que actualizarlo» no es una respuesta tan sencilla como parece.
Un pase de triaje más razonable
Esto no significa que haya que ignorarlo npm audit. Significa que hay que dejar de considerar que cada línea de salida tiene la misma urgencia, porque no es así.
Algunas cosas que realmente ayudan:
- La accesibilidad y la exposición priman sobre la gravedad por sí sola. Una vulnerabilidad CVE crítica en el código a la que no se puede acceder en tu entorno suele tener menor prioridad que una de gravedad moderada a la que se accede directamente en la gestión de tus solicitudes. Las clasificaciones de gravedad no conocen tu grafo de llamadas, pero tú sí.
- Separa el entorno de producción del de desarrollo y, a continuación, comprueba qué funciona. Una herramienta de compilación vulnerable y una dependencia de tiempo de ejecución vulnerable suelen requerir tiempos de respuesta diferentes.
npm audit --omit=devEs un primer paso útil, pero las herramientas de desarrollo que se ejecutan en la integración continua (CI) con credenciales, o el código que un empaquetador incluye en la versión final, siguen siendo importantes. - Agrupa por paquete, no por CVE. Una sola biblioteca obsoleta puede provocar varias alertas.
npm explain <package>muestra cuál de tus dependencias la ha incorporado, que suele ser donde se encuentra la solución real. - Establece una cadencia, con una vía de escape. Vuelve a realizar la auditoría semanalmente, o según un calendario que se ajuste a tu ciclo de lanzamiento, en lugar de volver a clasificar los incidencias cada vez que se actualice el feed. Actúa con mayor rapidez cuando haya indicios de explotación activa o de una exposición real a Internet.
- Que «ahora no» sea una respuesta válida. Una decisión documentada de posponer un asunto de baja importancia no equivale a ignorarlo. Anota por qué y cuándo se volverá a examinar, y luego sigue adelante.
Esta es la diferencia entre clasificar las notificaciones y simplemente borrarlas. Una de las dos opciones reduce realmente el riesgo.
Dónde encaja SecureChain
He aquí la distinción sobre la que conviene ser franco: npm audit Es de carácter orientativo. Te indica qué es lo que falla, y npm audit fix Se encarga de las correcciones sencillas, pero las decisiones difíciles siguen recayendo en ti. Es tu responsabilidad determinar si una actualización es válida y segura, si un parche necesita retroportarse o si un paquete al final de su vida útil (EOL) está siendo corregido siquiera en el código fuente original.
SecureChain actúa antes de que surja ese problema, en lugar de sumarse a la lista de alertas. El registro público ofrece cualquier archivo tar que haya publicado un responsable de mantenimiento. Las firmas del registro demuestran que no se ha modificado desde entonces, pero, a menos que el paquete incluya un certificado de procedencia, nada lo vincula con el repositorio de código fuente. SecureChain recompila los paquetes a partir de código fuente verificado en entornos aislados y reforzados, y los analiza en busca de malware y código sospechoso antes de que lleguen a tu árbol de dependencias. npm audit no está diseñado para detectar por sí mismo los «typosquats», las cuentas de mantenedores secuestradas ni los scripts de instalación maliciosos; solo informa de lo que ya figura en los avisos de seguridad. Los parches se ajustan a los tiempos de respuesta previstos, tanto si el desarrollador original sigue publicando correcciones como si ha dejado de hacerlo, y una vez que un paquete lleva meses sin que el desarrollador original haya publicado una nueva versión, Asistencia durante todo el ciclo de vida ofrece continuamente correcciones para la versión que ya utilizas.
Nada de esto hace que el triaje desaparezca. Lo que cambia es la cantidad de incertidumbre con la que se cuenta antes de que un paquete llegue a la compilación. Los paquetes se compilan y firman para cumplir con el nivel 3 de SLSA, y vienen con datos VEX y, dependiendo del paquete, con SBOM. Esa es la parte que nadie quiere crear a mano, pero que la mayoría de los equipos acaban necesitando para una auditoría. VEX aborda de forma más directa el problema del ruido, ya que especifica qué CVE conocidas afectan realmente a una versión concreta de un paquete.
Lo importante aquí es cambiar la perspectiva: SecureChain no es otro canal más que compite por tu atención. Se trata de que, para empezar, lleguen menos cosas a tu cola, porque gran parte del problema se ha resuelto antes de que se convirtiera en un problema para ti.
