Nueva guía de la ENISA: cómo protegerse del código sin auditar

Un paquete en npm, pip o Maven rara vez permanece como un único paquete. Tras el comando de instalación habitual suele arrastrarse una larga cadena de bibliotecas externas que se añaden automáticamente al proyecto junto con las dependencias directas y transitivas. En marzo de 2026 ENISA publicó una guía técnica sobre el uso seguro de los gestores de paquetes y examinó en detalle por qué esa práctica amplía la superficie de ataque casi sin que los propios equipos de desarrollo lo noten.
El problema hace tiempo que dejó de ser solo cuestión de conveniencia y velocidad. Los gestores de paquetes permiten añadir rápidamente una función preparada a una aplicación, sin escribir todo desde cero ni ensamblar los componentes manualmente. Pero junto con el ahorro de tiempo, el desarrollador introduce en el entorno de ejecución y de compilación código ajeno que el equipo no escribió, a menudo no leyó y casi nunca verificó por completo. Además, el volumen de ese código puede ser mucho mayor de lo que parece en el momento de la instalación.
Cada nueva biblioteca se integra en el grafo de dependencias del proyecto. A partir de ahí en el entorno aparecen no solo las dependencias directas que el desarrollador eligió conscientemente, sino también módulos adicionales traídos automáticamente. Parte de esos componentes puede no utilizarse en la ejecución del programa, pero incluso un módulo no usado conserva vulnerabilidades, historial de mantenimiento y riesgos asociados con la confianza en su autor y en el repositorio.
ENISA identifica dos clases principales de amenazas dentro de esas ecosistemas. La primera está relacionada con los propios paquetes: errores en el código, arquitecturas débiles, configuraciones inseguras y bibliotecas abandonadas sin mantenimiento. La segunda clase se refiere a ataques a la cadena de suministro del software, cuando el atacante no busca fallos en la aplicación lista, sino que intenta introducir código malicioso antes, en la etapa de publicación, actualización o resolución de dependencias.
Las bibliotecas populares son especialmente peligrosas. Un paquete ampliamente usado puede estar presente en decenas de miles de proyectos y convertirse en un soporte común para numerosos marcos, servicios y aplicaciones. En este esquema, una vulnerabilidad en un componente muy difundido se extiende rápidamente más allá del repositorio de origen. El problema se propaga por la cadena hacia abajo y afecta ya no a un solo producto, sino a una parte considerable de toda la ecosistema.
Con los paquetes abandonados la situación no es mejor. Una biblioteca puede permanecer años disponible en un repositorio público aunque su autor haya dejado de publicar correcciones y de velar por la seguridad. Un proyecto que siga dependiendo de ese componente hereda los problemas antiguos y a menudo no recibe parches durante meses o más. En la práctica esto significa que el código vulnerable permanece en el entorno de trabajo simplemente porque en su momento resultó una dependencia conveniente.
Un riesgo distinto lo crean los ataques a la cadena de suministro. En ese modelo el atacante publica un paquete malicioso, obtiene acceso a la cuenta de un mantenedor o interviene en el proceso de resolución de dependencias. A partir de ahí el componente peligroso puede llegar al proyecto mediante una instalación o actualización habitual, sin que nadie revise manualmente su contenido. La automatización que suele ayudar al desarrollo, en ese escenario empieza a operar en favor del atacante y difunde rápidamente el código malicioso a las aplicaciones downstream.
ENISA vincula la protección no a un único punto de control, sino a todo el ciclo de vida de la dependencia. La guía divide el trabajo en cuatro etapas: selección del paquete, integración en el proyecto, monitorización continua y remediación de los problemas detectados. Este enfoque es importante porque el riesgo no termina en el momento de la instalación: apenas comienza.
En la etapa de selección el equipo debe mirar no solo la popularidad de la biblioteca o la comodidad de la API. Importan el origen del paquete, la actividad de los mantenedores, el historial de vulnerabilidades, la reputación del repositorio y la existencia de señales de un mantenimiento adecuado. También es relevante comprobar firmas criptográficas y trabajar solo con registros de confianza. En esencia, la pregunta es si conviene permitir un componente concreto en el proyecto antes incluso de la primera instalación.
La integración exige otras medidas. ENISA recomienda fijar la composición del proyecto mediante un Software Bill of Materials, es decir, la lista de componentes incluidos en la compilación. Para la estabilidad del entorno son importantes los archivos lock de dependencias y la verificación de hashes, para que el conjunto de paquetes sea el mismo en distintos entornos. Tiene sentido incorporar el escaneo de vulnerabilidades en las canalizaciones de integración continua, de modo que los problemas conocidos se detecten durante la compilación y no después del lanzamiento.
Tras la instalación el trabajo no termina. El equipo debe vigilar nuevas publicaciones de CVE, cambios en el estado de versiones, la actividad de los mantenedores y señales de que el paquete envejece o cambia de propietario. Esa monitorización ayuda a ver el riesgo antes de que se convierta en un incidente. Para las dependencias de las que dependen partes críticas del sistema, el seguimiento regular hace tiempo que dejó de ser una medida deseable para convertirse en una práctica básica.
Cuando ya se detecta una vulnerabilidad, empieza la etapa de remediación. No basta con ver una entrada en la base de datos de CVE. Los desarrolladores deben entender si el problema es alcanzable en el sistema concreto y si realmente puede explotarse en el contexto operativo. Tras esa evaluación, el equipo decide qué hacer: actualizar el paquete, sustituir la biblioteca por una alternativa o aplicar un parche. No hay una respuesta universal, pero sin un análisis de explotabilidad la reacción suele convertirse en pánico o en una inacción peligrosa.
La guía hace además un énfasis importante relacionado con los cambios actuales en el desarrollo. ENISA señala que las herramientas de IA participan cada vez más en la escritura de código y con mayor frecuencia proponen bibliotecas listas durante el trabajo. Los grandes modelos de lenguaje (LLM) pueden recomendar dependencias que el desarrollador no ha estudiado ni elegido conscientemente. Como resultado, llega código nuevo al proyecto, pero la decisión de añadirlo la toma en la práctica la sugerencia en la interfaz, no una persona.
Para los equipos que ya han integrado asistentes de IA en el desarrollo, de ello se desprende una conclusión directa: cualquier biblioteca sugerida por el modelo debe pasar las mismas comprobaciones que un paquete encontrado manualmente. No debe haber concesiones para las recomendaciones de LLM. De lo contrario, la automatización empieza a incrementar sin que se note la dependencia de componentes cuya procedencia y seguridad nadie evaluó adecuadamente.
En resumen: las cadenas de dependencias que generan los gestores de paquetes ya son parte esencial del desarrollo moderno. Es casi imposible prescindir de ellas. Pero cada nueva instalación amplía la cadena de suministro más allá de la propia aplicación. Por eso el trabajo seguro con dependencias debe abarcar todo el recorrido del paquete, desde la selección y la instalación hasta la monitorización y la sustitución tras la aparición de una vulnerabilidad. Sin ese control, un comando de instalación conveniente se convierte con facilidad en código ajeno dentro del propio proyecto.