Un proyecto web mediano declara veinte o treinta dependencias en su archivo de manifiesto. Si mirás lo que realmente se instala, la cifra suele ser varias veces mayor. Cada uno de esos paquetes se ejecuta dentro de tu aplicación, con los mismos permisos que tu propio código, y fue escrito y publicado por gente que no conocés. Eso es la cadena de suministro de software, y no se resuelve con un escaneo ocasional.
Directas y transitivas
Las dependencias directas son las que elegiste. Las transitivas son las que traen esas, y las de esas, y así. Una vulnerabilidad aparece muchas veces en un paquete que ni sabías que usabas, enterrado tres niveles abajo. Por eso el primer paso es poder ver el árbol completo: todos los gestores de paquetes tienen un comando para listarlo, y conviene mirarlo al menos una vez para dimensionar qué estás cargando.
Una consecuencia práctica: arreglar una transitiva a veces implica esperar que el paquete intermedio publique una versión actualizada, o forzar una resolución a mano mientras tanto. Documentá ese parche temporal, porque si no se queda para siempre.
Archivos de bloqueo
El archivo de bloqueo (lockfile) fija las versiones exactas que se resolvieron, incluidas las transitivas. Versionalo siempre en las aplicaciones y usalo en la construcción y el despliegue, de modo que lo que probaste sea lo que corre. Sin él, dos instalaciones del mismo proyecto en días distintos pueden traer código diferente, y una versión maliciosa publicada anoche entraría en tu próxima compilación sin que nadie haya decidido nada.
Para las bibliotecas que publicás vos, el criterio es otro: declarás rangos compatibles y dejás que cada aplicación fije los suyos.
Auditoría automática y actualización periódica
La mayoría de los gestores de paquetes incluye una auditoría que compara tus dependencias contra bases públicas de vulnerabilidades conocidas. Correla en la integración continua y hacé que un hallazgo grave frene la compilación, o al menos genere un aviso que alguien tenga que mirar. Hay también servicios que abren automáticamente propuestas de actualización.
Dos advertencias. La auditoría solo conoce lo que ya fue reportado, así que un resultado limpio no significa ausencia de problemas. Y no toda alerta aplica a tu caso: si la falla está en una función que tu código nunca invoca, la urgencia es menor, aunque igual conviene actualizar cuando sea simple.
Sobre el ritmo de actualización, el extremo cómodo es no tocar nada hasta que algo se rompe. Cuando por fin hay que subir de versión, el salto es enorme y el riesgo de regresión también. Es más barato actualizar de a poco y seguido, con las pruebas automáticas como respaldo. Reservá un rato fijo del mes para eso y tratalo como mantenimiento normal, no como urgencia.
Evaluar antes de agregar
Instalar un paquete es una decisión de confianza. Antes de sumar uno, fijate algunas cosas que se ven en minutos:
- Si lo mantienen activamente y si hay más de una persona con capacidad de publicar.
- Cuánto código trae y cuántas dependencias arrastra. Una utilidad de cinco líneas no justifica un árbol de cuarenta paquetes.
- Si lo necesitás de verdad o si la librería estándar del lenguaje ya lo resuelve.
- Si el nombre es exactamente el que buscabas.
Esto último apunta al typosquatting: publicar paquetes con nombres casi idénticos a los populares, esperando que alguien se equivoque al tipear un comando de instalación o copie un nombre mal de un foro. Revisá el nombre letra por letra, y desconfiá de paquetes recién creados que prometen lo mismo que uno conocido.
También existe la confusión de dependencias, donde un nombre interno de tu empresa coincide con uno del registro público y el gestor termina trayendo el equivocado. Si usás paquetes privados, configurá explícitamente de qué registro sale cada uno.
Saber qué tenés
Cuando se publica una vulnerabilidad grave en una librería muy usada, la pregunta de la mañana es siempre la misma: ¿la usamos y en qué versión? Responderla en cinco minutos o en tres días depende de tener un inventario. Una lista de componentes de software (SBOM) es justamente eso, un listado legible por máquinas de lo que contiene cada entrega, y varias herramientas la generan sin esfuerzo.
Reaccionar sin entrar en pánico
Ante un aviso, el recorrido razonable es: confirmar si estás afectado, evaluar si la falla es alcanzable desde tu aplicación, actualizar o aplicar la mitigación que indique el aviso, y desplegar. Registrá qué decidiste y por qué. Si tenés clientes que dependen de tu software, saber contestarles con precisión cuánto tardaste y qué hiciste vale más que cualquier promesa genérica de que "tomás la seguridad en serio".