← Blog

Gestión de vulnerabilidades de código abierto en tus dependencias

Guía práctica de gestión de vulnerabilidades open source: halla dependencias vulnerables, prioriza con CVSS, EPSS, KEV y reachability, y remedia CVEs.

Bruno Baldo·Sep 28, 2026·Actualizado el Sep 14, 2026·13 min de lectura·Revisado por Rainforest Technologies

El código abierto es el sustrato del software moderno. Las bibliotecas que instalas, y las bibliotecas de las que dependen esas bibliotecas, componen la mayor parte de lo que realmente llega a producción, lo que significa que la seguridad de tu aplicación es, en gran medida, la seguridad de un código que no escribiste. La gestión de vulnerabilidades open source es la disciplina de encontrar, priorizar y remediar las dependencias vulnerables en ese suministro de código de terceros antes de que lo haga un atacante. Es una práctica central dentro del análisis de composición de software, y hacerlo bien es la diferencia entre un scanner que genera ruido y un programa que reduce el riesgo de forma medible.

Este artículo es una inmersión a fondo en el lado de las vulnerabilidades del SCA: de dónde vienen las vulnerabilidades en dependencias, cómo distinguir una que es genuinamente urgente de una que es solo severa, y cómo funciona en realidad la remediación de CVEs cuando la falla está enterrada tres niveles por debajo en tu árbol de dependencias.

De dónde vienen las vulnerabilidades en dependencias

Toda dependencia que agregas es código que se ejecuta con los privilegios de tu aplicación, y viene con su propio historial de fallas descubiertas. Esas vulnerabilidades llegan por dos puertas.

Las dependencias directas son los paquetes que instalaste deliberadamente: los que figuran en tu package.json, pom.xml, requirements.txt o go.mod. Los elegiste, puedes verlos y, cuando uno tiene una vulnerabilidad, la corrección suele estar bajo tu control.

Las dependencias transitivas son las que tus dependencias directas incorporan, y las que esas incorporan, de forma recursiva. Un solo paquete que instalas puede arrastrar sin ruido decenas de otros. Aquí es donde realmente vive la mayor parte del riesgo: los estudios de proyectos reales encuentran de forma consistente que las dependencias transitivas superan con creces a las directas, y son justamente el código que la mayoría de los equipos nunca mira. Una vulnerabilidad en un paquete del que nunca oíste hablar, importado por un paquete del que nunca oíste hablar, sigue ejecutándose en tu aplicación. Como esta exposición indirecta es tan fácil de pasar por alto, merece un tratamiento propio: consulta dependencias transitivas y seguridad para ver el panorama completo.

La consecuencia práctica es que no puedes gestionar lo que no puedes enumerar. La primera tarea de la gestión de vulnerabilidades open source es producir un inventario completo y resuelto de cada dependencia del árbol, directa y transitiva, en las versiones exactas que realmente se van a ejecutar.

Las bases de datos e identificadores de vulnerabilidades

Un inventario de dependencias solo se vuelve útil cuando lo cruzas con vulnerabilidades conocidas, y estas viven en bases de datos públicas con sus propios identificadores.

  • CVE (Common Vulnerabilities and Exposures) es el esquema de nomenclatura universal. Un ID de CVE como CVE-2021-44228 es una etiqueta estable y globalmente única para una falla específica, y es el identificador al que todo lo demás hace referencia.
  • NVD (National Vulnerability Database) enriquece los CVEs con puntajes de severidad, rangos de versiones afectadas y referencias. Es autoritativa, pero no siempre rápida; puede haber un retraso entre que un CVE se publica y que la NVD lo analiza por completo.
  • GHSA (GitHub Advisory Database) publica avisos vinculados a ecosistemas de paquetes específicos (npm, PyPI, Maven, etcétera). Como los avisos se expresan en términos de nombres de paquetes y rangos de versiones reales, se mapean de forma limpia sobre tu árbol de dependencias, y a menudo aparecen antes de que la NVD los alcance.
  • OSV (Open Source Vulnerabilities) es un schema y una base de datos agregada diseñada específicamente para el código abierto. Normaliza avisos de muchos ecosistemas en un formato legible por máquina y preciso en cuanto a la versión, lo que hace que la correspondencia automatizada sea mucho más confiable que interpretar rangos de versiones en texto libre.

Un buen conjunto de herramientas recurre a varias de estas fuentes a la vez, porque ninguna fuente aislada es completa ni oportuna para todos los ecosistemas. El identificador que las ata es el CVE, pero son los avisos específicos de cada ecosistema (GHSA, OSV) los que suelen permitir que un scanner afirme con precisión que tu versión instalada está afectada.

Puntuación y priorización: severidad no es urgencia

Si tratas cada CVE divulgado como una emergencia, agotarás a tu equipo mucho antes de quedarte sin avisos. La destreza en la gestión de vulnerabilidades open source está en la priorización: separar el puñado de vulnerabilidades que de verdad te amenazan de las muchas que no. Cuatro señales, usadas en conjunto, lo hacen posible.

CVSS (Common Vulnerability Scoring System) entrega un puntaje de severidad de 0 a 10. El número que sueles ver es el puntaje base, que describe las características intrínsecas de la falla en abstracto. Pero el CVSS también define un puntaje ambiental que se ajusta a tu contexto: si el componente afectado está expuesto, qué comprometería en realidad en tu sistema. Un base 9,8 en una biblioteca que solo se ejecuta en una herramienta de desarrollo aislada en un sandbox no representa el mismo riesgo que un base 7,5 en tu servicio de autenticación expuesto a internet. La severidad base es un punto de partida, no un veredicto.

EPSS (Exploit Prediction Scoring System) responde a otra pregunta: ¿qué tan probable es que esta vulnerabilidad se explote en entornos reales en el corto plazo? Lo expresa como una probabilidad. Una falla de CVSS alto con un EPSS muy bajo suele ser de menor prioridad que una falla de CVSS moderado que los atacantes están sondeando activamente.

KEV (el catálogo Known Exploited Vulnerabilities de la CISA) es la señal más fuerte de todas: lista vulnerabilidades cuya explotación en el mundo real está confirmada. Si un CVE de tu árbol está en la lista KEV, pasa al frente de la fila sin importar sus otros puntajes. Esto deja de ser un riesgo teórico.

Reachability despeja el resto del ruido. Una vulnerabilidad solo importa si la ruta de código vulnerable es invocada realmente por tu aplicación. El análisis de reachability rastrea si tu código —o el código de tus dependencias— llama en algún momento a la función afectada. Si la función vulnerable nunca se alcanza, el CVE puede ser un caso genuino de falsa urgencia: presente en el inventario, pero no explotable en tu uso. La reachability es una de las formas más eficaces de reducir una cola de triaje de cientos de hallazgos a las pocas decenas que están realmente activas.

En conjunto, la pregunta de priorización no es "¿qué tan severo es esto?", sino "¿es severo, probable de ser explotado, de explotación conocida y alcanzable en nuestra aplicación?" Esa visión compuesta convierte la salida en bruto de un scanner en una lista de trabajo priorizada y accionable.

Remediar dependencias directas vs. transitivas

Una vez que sabes qué corregir, la ruta de remediación depende en gran medida de si el paquete vulnerable es una dependencia directa o transitiva.

Para las dependencias directas, las opciones son relativamente limpias:

  • Actualizar a una versión parcheada. Es la opción por defecto y casi siempre la respuesta correcta: la mayoría de los CVEs se corrigen en un release posterior.
  • Aplicar un patch a la vulnerabilidad específica, cuando un mantenedor o tu herramienta ofrece una corrección puntual sin un salto completo de versión.
  • Reemplazar el paquete por una alternativa mantenida si el proyecto está abandonado y nunca se va a corregir.
  • Aceptar el riesgo con una justificación documentada cuando la vulnerabilidad genuinamente no es alcanzable o no es aplicable, dejando registro del porqué para que la decisión sea auditable y no reaparezca como ruido en cada scan.

Para las dependencias transitivas, tienes un problema más difícil: no puedes simplemente actualizar un paquete que nunca importaste. Los enfoques son:

  • Actualizar el paquete padre que incorpora la dependencia transitiva vulnerable, para que resuelva de forma natural a una versión corregida. Es la corrección más limpia cuando existe un padre más nuevo.
  • Forzar una versión segura usando el mecanismo de override de tu gestor de paquetes: overrides en npm, resolutions en Yarn, dependencyManagement en Maven, archivos de constraints en pip. Le indican al resolver que use una versión parcheada del paquete transitivo aunque nada lo haya declarado directamente. Úsalos con cuidado: estás sobrescribiendo lo que un mantenedor esperaba.
  • Reemplazar o aceptar, igual que con las dependencias directas, cuando no existe una ruta de actualización.

En ambos casos, la corrección debe verificarse: subir una versión puede resolver un CVE e introducir otro, así que la remediación va seguida de un nuevo scan, no se da por concluida.

El problema de la actualización

Si actualizar siempre funcionara sin fricciones, la gestión de dependencias sería un problema resuelto. No lo es, y esa fricción es la razón por la que las dependencias vulnerables se quedan.

La tensión central es mantenerse al día versus mantenerse estable. Una actualización de versión mayor para corregir un CVE puede traer cambios de API que rompen la compatibilidad y fuerzan una refactorización que no habías presupuestado. Los equipos que se quedan atrás —anclados en una versión mayor antigua porque actualizar es doloroso— suelen descubrir que la versión parcheada está a varios releases incompatibles de distancia, y así una corrección de seguridad se convierte en un proyecto de migración.

Los lockfiles (package-lock.json, yarn.lock, poetry.lock, go.sum) son esenciales aquí. Fijan la versión resuelta exacta de cada dependencia, directa y transitiva, para que los builds sean reproducibles y el resultado de un scan corresponda de verdad a lo que se entrega. Pero un lockfile también congela versiones vulnerables en su lugar hasta que lo actualizas deliberadamente, y por eso regenerar y revisar los lockfiles forma parte del mantenimiento de rutina y no de un paso único.

La respuesta duradera es hacer las actualizaciones pequeñas y frecuentes, en lugar de grandes y esporádicas. Mantenerse razonablemente al día significa que cada actualización de seguridad es un salto menor en vez de un brinco de varias versiones, y te mantiene lo bastante cerca de los releases mantenidos como para que una corrección suela estar a una actualización de distancia.

Responder a la divulgación de un zero-day

Cada tanto aparece una vulnerabilidad que convierte la gestión de dependencias de higiene rutinaria en una carrera con todo el mundo movilizado: una biblioteca ampliamente usada, una falla crítica explotable de forma remota, explotación activa en cuestión de horas. La divulgación de Log4Shell en la biblioteca Log4j es el ejemplo de referencia: incontables aplicaciones se vieron afectadas por un uso profundamente transitivo, y la pregunta más difícil para la mayoría de las organizaciones fue simplemente ¿estamos siquiera afectados, y dónde?

Aquí es donde rinde el trabajo previo. Un software bill of materials (SBOM) actualizado convierte esa auditoría manual, angustiante y de días, en una consulta: busca en tus SBOMs el paquete y el rango de versiones afectados y tendrás tus aplicaciones expuestas en minutos. Una herramienta de SCA que cruza continuamente tu inventario con los nuevos avisos puede señalar el CVE recién divulgado en todo tu parque en el momento en que se publica.

Conviene ser honestos sobre los límites. Un SBOM y el SCA aceleran drásticamente el análisis de impacto; no te vuelven inmune. Todavía tienes que actualizar, sobrescribir o mitigar y, si aún no existe un patch, quizá necesites una solución temporal. Lo que una buena herramienta te compra es velocidad y certeza sobre el alcance, lo que, en las primeras horas de un zero-day, suele ser la diferencia entre una respuesta controlada y el caos.

Monitoreo continuo

El cambio de mentalidad más importante de todos es este: una dependencia que es segura hoy puede ser vulnerable mañana. No cambiaste nada: cambió el mundo. Se divulga un nuevo CVE contra una versión que entregaste hace meses y, de repente, una aplicación limpia tiene un hallazgo crítico.

Esa realidad hace insuficiente el scanning en un punto único en el tiempo. La gestión de vulnerabilidades open source tiene que ser continua: tus artefactos desplegados y sus SBOMs se reevalúan contra las bases de datos a medida que llegan nuevos avisos, y alguien recibe una notificación cuando una dependencia antes limpia se vuelve vulnerable. Monitorear el software que ya ejecutas es tan importante como escanear el código que estás por entregar.

Gating en CI/CD, SLAs y control del ruido

Para operacionalizar todo esto, la mayoría de los programas maduros converge en unas pocas prácticas.

Pon una compuerta en el pipeline. Integra el SCA en el CI para que un pull request que introduzca una dependencia vulnerable quede señalado en el cambio que lo causó, cuando la corrección es más barata. Haz que el build falle ante nuevos hallazgos por encima de un umbral acordado, en lugar de ante todo el backlog, para que la compuerta bloquee el riesgo nuevo sin mantener cada build rehén de la deuda histórica.

Define SLAs por severidad. Define, y acuerda con ingeniería, con qué rapidez debe remediarse cada nivel; por ejemplo, hallazgos críticos y listados en KEV en días, altos en semanas y severidades menores en una cadencia de rutina. Atar el reloj a la severidad priorizada (no al CVSS en bruto) mantiene los compromisos realistas y enfocados en el riesgo real.

Controla el ruido, deliberadamente. La forma más rápida de matar un programa de SCA es inundar a los desarrolladores con hallazgos sobre los que no pueden actuar. Usa la reachability para suprimir CVEs inalcanzables, deduplica la misma vulnerabilidad que aparece en muchos servicios y deja registro de las decisiones de riesgo aceptado para que no reaparezcan en cada scan. La meta es una lista corta y confiable: cada ítem real, priorizado y con dueño.

Ninguno de estos riesgos de dependencia existe aislado del resto de la seguridad de tu aplicación. Los componentes vulnerables y desactualizados siguen siendo una de las categorías de riesgo del OWASP Top 10 (2025), y las fallas de la cadena de suministro de software se registran como la categoría A03, un reconocimiento directo de que el código que incorporas es hoy una de las principales vías por las que se comprometen las aplicaciones. La gestión de vulnerabilidades open source es la forma de abordar esa categoría en la práctica. Consulta OWASP para ver cómo encaja en el panorama de riesgo más amplio.

Cómo ayuda Rainforest

Hacer todo esto a mano —resolver el árbol de dependencias completo, cruzarlo con varias bases de datos de vulnerabilidades, puntuar hallazgos en CVSS, EPSS, KEV y reachability, y hacer seguimiento de la remediación a lo largo del tiempo— es exactamente el trabajo que la herramienta de SCA existe para automatizar. Rainforest lleva el análisis de composición de software a tu pipeline para que puedas inventariar cada dependencia directa y transitiva, sacar a la luz los CVEs que de verdad afectan las versiones que ejecutas, y priorizarlos por la probabilidad de explotación y la reachability en lugar de por la severidad en bruto. Como Rainforest genera y monitorea continuamente un SBOM para tus aplicaciones, un zero-day recién divulgado se vuelve una búsqueda en todo tu parque en lugar de un simulacro de incendio, y la orientación de remediación te apunta a la actualización o el override que realmente elimina el hallazgo.

Si quieres poner bajo control la gestión de vulnerabilidades open source en todo tu árbol de dependencias, agenda una demostración y la recorreremos contigo usando tus propias aplicaciones.

Preguntas frecuentes

¿Qué es la gestión de vulnerabilidades open source?

La gestión de vulnerabilidades open source es la práctica de encontrar, priorizar y remediar vulnerabilidades conocidas en las dependencias de código abierto de terceros que usan tus aplicaciones, tanto los paquetes que instalas directamente como los transitivos que esos paquetes incorporan. Implica construir un inventario completo de dependencias, cruzarlo con bases de datos de vulnerabilidades como NVD, GitHub Advisories y OSV, ordenar los hallazgos por riesgo en el mundo real, remediarlos mediante actualizaciones u overrides, y monitorear continuamente el software desplegado a medida que se divulgan nuevas vulnerabilidades. Es una parte central del análisis de composición de software.

¿Cuál es la diferencia entre CVSS y EPSS?

El CVSS (Common Vulnerability Scoring System) mide qué tan severa es una vulnerabilidad: su impacto técnico intrínseco, en una escala de 0 a 10. El EPSS (Exploit Prediction Scoring System) mide qué tan probable es que una vulnerabilidad se explote en entornos reales en el corto plazo, expresado como una probabilidad. Responden a preguntas distintas: una falla puede ser muy severa (CVSS alto) y, aun así, improbable de ser explotada (EPSS bajo), o moderadamente severa y ser objetivo activo. Usados en conjunto —idealmente junto al catálogo KEV de la CISA y el análisis de reachability— dan una idea mucho mejor de la urgencia real que la severidad por sí sola.

¿Cómo corrijo una vulnerabilidad en una dependencia transitiva?

Como nunca importaste una dependencia transitiva de forma directa, por lo general no puedes simplemente actualizarla. La corrección más limpia es actualizar la dependencia directa (el padre) que la incorpora, para que resuelva a una versión parcheada. Si no existe una versión de padre adecuada, usa el mecanismo de override de tu gestor de paquetes —overrides en npm, resolutions en Yarn, dependencyManagement en Maven, o un archivo de constraints en pip— para forzar al resolver a una versión segura. Si ninguno funciona, puedes reemplazar el paquete problemático o, cuando la falla es genuinamente inalcanzable, aceptar el riesgo con una justificación documentada. Vuelve a escanear siempre después para confirmar la corrección.

¿Qué es el análisis de reachability?

El análisis de reachability determina si la ruta de código vulnerable en una dependencia es invocada realmente por tu aplicación. Un paquete puede contener un CVE grave que nunca te importa porque tu código —y el resto del árbol de dependencias— nunca llama a la función afectada. Al rastrear qué funciones vulnerables son genuinamente alcanzables, este análisis filtra los hallazgos que están presentes en tu inventario pero no son explotables en tu uso, lo que reduce drásticamente la falsa urgencia y permite a los equipos concentrar el esfuerzo de remediación en las vulnerabilidades que están realmente activas.

¿Con qué frecuencia debo escanear dependencias?

Continuamente. El scanning debe ocurrir en el CI ante cada cambio, para que las nuevas dependencias vulnerables se detecten en el pull request que las introduce, y también debe ejecutarse de forma continua contra tus artefactos desplegados y sus SBOMs. La razón es que una dependencia segura hoy puede ser vulnerable mañana: se divulgan nuevos CVEs contra versiones que ya entregaste sin que tú cambies nada. Un scan único captura un solo momento; solo el monitoreo continuo detecta las vulnerabilidades que surgen en código que ya se ejecuta en producción.

Bruno Baldo

Escrito por

Bruno Baldo

CMO

Um pouco de marketing e um pouco de curiosidade e temos a receita pra criar um apaixonado por cyber!

Siga leyendo