Introducción
En el desarrollo de software la velocidad del mercado suele marcar un antes y un después en los proyectos. Pocos proyectos suelen mantener la misma velocidad que el mercado demanda en cuestión de nuevas técnologías, actualizaciones y gestión de dependencias dentro de un proyecto.
Además, el uso de software open-source dentro nuestros proyectos puede llegar a generar brechas de seguridad que deben ser subsanadas en un corto periodo de tiempo con el objetivo de que nuestro software sea lo más confiable posible.
En este artículo vamos a explorar dos herramientas que nos van a permitir que nuestros proyectos puedan mantenerse actualizados de manera automática de una manera transparente y muy incremental. Vamos a explorar el stack de https://www.mend.io/ y en concreto dos de sus principales herramientas como son Renovate y Bolt.
Renovate
Renovate es una herramienta que nos va a permitir automatizar en tiempo real la actualización de dependencias de nuestro software. Sea cual sea su lenguaje y de una manera natural usando pull requests sobre nuestros proyectos.
Actualmente Renovate ofrece soporte sobre las siguientes plataformas:
- Github
- GitLab
- Bitbucket
- Azure DevOps
- Gitea
Y como veremos en el ejemplo, es capaz de analizar en profundidad todo el stack que estamos usando en nuestro proyecto y proponernos actualizaciones sobre las dependencias que estemos usando. Además es altamente configurable.
Toda la información sobre la herramienta la podéis encontrar aquí. En los siguientes puntos del artículo veremos con un ejemplo completo como configurar Renovate y como se lanza el proceso completo de actualización.
Bolt
Bolt sigue la misma teoría que su hermano Renovate, pero centrado en la detección de vulnerabilidades de nuestro código. Además nos va a sugerir parches y recomendaciones sobre cada una de las alertas que nos reporte.
De la misma manera que Renovate, Bolt soporta un amplio número de lenguajes y frameworks a los que da soporte y basa su fuente de datos en los principales sistemas de seguimiento de problemas de proyectos OpenSource.
Renovate, ejemplo de uso
En el siguiente ejemplo vamos a mostrar como funciona Renovate, para ello lo primero será crear una aplicación en la cual podamos incluirle una serie de dependencias para que Renovate sea capaz de actualizar.
-
Creación de la aplicación
En nuestro ejemplo vamos a trabajar con una aplicación basada en Spring Boot con Docker, para ello el primer paso va a ser crearnos con el starter de spring una aplicación de ejemplo con las siguientes dependencias:
- spring-web
- lombok
- azure key vault
- cloud-bus
En el siguiente enlace tenéis la petición a la API de Spring Initializr que permite crear la aplicación.
Además, vamos a crearle un fichero DockerFile y un fichero DockerCompose para gestionar el contenedor y el entorno local de integración con una serie de imágenes de ejemplo (para ver como Renovate también gestiona este tipo de dependencias).
En el siguiente repositorio de GitHub tenéis el TAG v0.1 con la versión final a nivel de dependencias.
-
Instalación de Renovate en GitHub.com, en nuestro caso vamos a usar la integración con GitHub para gestionar la automaticación de nuestro repositorio. Para ello, basta con ir al marketplace de Github, e instalar Renovate.
Una vez instalado podemos dar acceso a todos nuestros repositorios o ir configurándolos bajo demanda, en este último caso basta con ir a Settings -> Applications -> Renovate (Configure) y en la parte final de la configuración, añadir el repositorio que queramos instrumentar con Renovate.
-
Una vez Renovate está configurado vamos a echar un vistazo que empieza a ocurrir en background.
En el repositorio, se os abrirá automaticamente la primera PR de Renovate, con el objetivo de configurar vuestro repositorio. En nuestro ejemplo no haremos configuración adicional, pero si tenéis más interés podéis ver el siguiente enlace.
-
Una vez aceptamos la PR, nuestro proyecto queda configurado para ser gestionado a nivel de dependencias con Renovate. En este momento Renovate escaneará nuestro proyecto en busca de actualizaciones.
-
Al cabo de algunos minutos en el proyecto se empezarán a recibir distintas PR's. Pero además nos aparecerá un nuevo "Issue", llamado Dependency Dashboard.
Este dashboard nos permite operar directamente con las dependencias detectadas usando markdown. Sobre el dashboard, podéis encontrar toda la información aquí. Podríamos quitarlo, pero en este caso vamos a ver el contenido del mismo y nos ofrece:
-
En nuestro caso, nos informa de las PR's abiertas y la posibilidad de gestionar en una única PR la actualización dependencias maven o gestionarlas de una en una. Una vez seleccionada la opción deseada, sin hacer nada, podemos ver que nuevas PR's se van creando.
-
Si exploramos las PR's del repositorio nos encontramos con lo siguiente:
-
Actualización de las imágenes usadas en DockerCompose.
-
Actualización de la imagen base de nuestra aplicación a nivel de docker
-
Actualización de nuestro pom.xml con las distintas versiones que deben actualizarse. Es muy interesante como la actualización soporta distintos tipos como son la actualización de properties como de parents.
-
Otro punto a tener en cuenta son las estadísticas ofrecidas en la PR a nivel de dependencia, nos ofrecen 4 métricas para cada una de las dependencias:
- Age: El tiempo que lleva la nueva versión liberada.
- Adoption: El grado de adopción en la comunidad.
- Passing: El porcentaje de tests que pasaron los proyectos que aplicaron este cambio.
- Confidence: Grado de Confiabilidad.
-
-
Conforme se van aceptando y mergeando las PR's, el Issue creado por Renovate se va actualizando hasta no dejar ninguna tarea pendiente.
Bolt, ejemplo de uso
De la misma manera que en el ejemplo anterior, Bolt nos va a permitir detectar posibles vulnerabilidades en nuestro proyecto de GitHub. En este caso usaremos el mismo ejemplo anterior para configurar Bolt.
-
Configurar Bolt en nuestro repositorio de GitHub. De la misma manera que Renovate, en el marketplace obtendremos Bolt.
-
Y siguiendo los mismos pasos que para Renovate, configuraremos nuestro repositorio para que se integre con la aplicación. Una vez hecho, recibimos la primera PR para configurar el repositorio con Bolt.
-
En nuestro ejemplo vamos a añadir una dependencia que expone ciertas vulnerabilidades, como por ejemplo Apache Commons Text versión 1.9. En este caso las vulnerabilidades son: CVE-2022-42889 y CVE-2022-42889.
Por tanto, hacemos un commit al proyecto añadiendo dicha librería.Al cabo de cierto tiempo aparecerá el issue asociado a la vulnerabilidad.
-
Al cabo de los minutos no sólo nos aparece la vulnerabilidad añadida de manera consciente si no que el uso de la última versión de spring-boot web (2.7.4) conlleva por transitividad otra serie de vulnerabilidades.
-
Podemos ver que la información en el Issue es bastante completa, indicando si es posible como podemos solventar el problema, ya sea por subida de versión o de otra manera. Además del enlace a la vulnerabilidad detectada y el detalle de la misma.
-
En nuestro caso, podemos solventar la de apache commons subiendo la versión 1.10 y por tanto, lo hacemos.
-
En el siguiente ciclo de escaneo del código Mend Bolt detecta que dicha vulnerabilidad ha sido solventada y cierra automáticamente el Issue, añadiendo un comentario y modificando el título con autoclosed
Conclusiones
En este artículo hemos visto como de manera sencilla podemos mantener actualizados y libres de vulnerabilidades nuestros proyectos.
Renovate y Bolt son dos herramientas con muy buenas capacidades de integración y con una experiencia de usuario altamente gratificante por tanto ya sea para tus proyectos personales como incluso a nivel empresarial deben ser tomadas en cuenta como una opción de automatización para la detección de dependencias obsoletas y vulnerabilidades.
En el mercado existen otras alternativas como Dependabot, IssueTrak o GuardRails entre otras. Si has usado alguna de ellas no dudes en darnos tu feedback en los comentarios.