Cómo gestionar vulnerabilidades de seguridad en Spring Boot
29 de noviembre de 2023
0 minutos de lecturaEn el mundo del desarrollo de software, gestionar las dependencias es una parte fundamental para crear aplicaciones sólidas y seguras. Spring Boot, una herramienta popular entre los desarrolladores de Java, facilita la creación de aplicaciones, pero hay más de lo que parece. Mantener tus dependencias bajo control es crucial para que tus proyectos de Spring Boot funcionen sin problemas y sean resilientes frente a amenazas que evolucionan constantemente.
Un aspecto fundamental de la gestión de dependencias en Spring Boot es la seguridad. Con frecuencia se descubren vulnerabilidades de software, y mantener actualizadas las dependencias de tu proyecto es como ponerte una armadura de seguridad digital. Las dependencias desactualizadas son como puertas sin llave que invitan a las amenazas a entrar, y eso es algo que queremos evitar.
Cómo encontrar vulnerabilidades en Spring Boot
Las herramientas de análisis de composición de software (SCA) son muy útiles para los desarrolladores. Ofrecen una solución sencilla para gestionar dependencias, manejar vulnerabilidades de seguridad, resolver problemas de licencias y garantizar el cumplimiento en tus proyectos de software. Si usas Snyk Open Source como herramienta SCA, puedes descubrir fácilmente si tus paquetes de Spring Boot tienen vulnerabilidades.
En mi proyecto de ejemplo, encontré varias vulnerabilidades. La primera es un problema de seguridad de gravedad alta en `netty-codec-http2`. Se trata de una dependencia transitiva que incluye `spring-boot-start-webflux`, como puedes ver a continuación.

La segunda vulnerabilidad que quiero mencionar es un problema de ejecución de código arbitrario de gravedad media que incluye el paquete `snakeyaml`. También es una dependencia transitiva, en este caso incluida por `spring-boot-starter-security`.

Hoy no profundizaré en el problema concreto de cada vulnerabilidad, pero puedes consultar la publicación del blog dedicada para obtener más información sobre el problema de `snakeyaml`. Enfoquémonos en resolverlo e implementar la mejor solución.
Cómo corregir paquetes vulnerables en tu aplicación Spring Boot
Para la primera vulnerabilidad, hay una solución clara. Mi aplicación se basa en Spring Boot 2.7.16 y, por lo tanto, `spring-boot-starter-webflux` también está en la versión 2.7.16.
Actualizar el starter de Webflux a la versión 2.7.17 debería resolver el problema. Hay varias maneras
de hacerlo, pero no todas son recomendables.
Por lo general, el manifiesto de Spring Boot se ve así:
Maven:
Gradle:
Actualizar el starter de Spring Boot
El número de versión de cada `spring-boot-starters` se deriva de `spring-boot-starter-parent` (Maven) o del complemento `org.springframework.boot` en Gradle.
La razón principal es que todos estos paquetes starter pertenecen a la misma versión de Spring y se prueban como un conjunto.
Al revisar la primera vulnerabilidad encontrada en mi proyecto, la recomendación de corrección es actualizar `spring-boot-starter-webflux` a la versión 2.7.17 para resolver la vulnerabilidad de seguridad de gravedad alta. Esto sugiere que solo tengo que corregir el paquete Webflux, lo cual puedo hacer especificando una versión concreta, como la siguiente.
Maven:
Gradle:
¡Pero espera! Esta no es la forma recomendada de resolver el problema. Se usa la versión específica 2.7.17 en lugar de la versión del paquete principal. Aunque podría funcionar porque se trata de una versión de parche, no es la solución más segura ni la mejor. Como semver no garantiza que las API se mantengan intactas, no podemos estar seguros de que esto funcione. Pero el argumento más importante es que probablemente haya una nueva versión completa de Spring Boot.
¿Recuerdas que te dije que estos starters van juntos? Por eso, lo mejor que puedes hacer es actualizar toda la distribución de Spring Boot a la versión 2.7.17. Esto es aún más importante con versiones menores o mayores de un paquete, ya que pueden romper las API e impedir que funcionen bien en conjunto. Así que, en este ejemplo, actualiza el paquete principal (Maven) o el complemento (Gradle), en lugar de los starters individuales.
Maven:
Gradle:
Te recomiendo hacer un esfuerzo adicional y actualizar toda tu versión de Spring Boot a la versión adecuada más reciente. Para saber cuál es, solo tienes que ir a https://start.spring.io.

Cómo actualizar dependencias transitivas
Para el segundo problema, Snyk detectó que mi aplicación no tiene una recomendación de corrección clara. Actualmente, tampoco hay una versión disponible de `spring-boot-starter` que no tenga esta dependencia transitiva insegura. Lo que sí sabemos es que hay una versión actualizada de la dependencia transitiva. Actualizar a `snakeyaml` 2.0 resolverá el problema.
Una vez más, quiero enfatizar que esto es solo un ejemplo. Es posible que ya haya una versión actualizada de `spring-boot-starter` disponible cuando leas esto, así que no olvides verificarlo. Para obtener información sobre la vulnerabilidad de SnakeYaml, consulta la publicación dedicada del blog sobre este tema.
Actualizar el parámetro de versión
Lo primero que debes hacer es verificar si la versión del paquete que quieres actualizar es una propiedad de Spring Boot. La documentación de Spring Boot incluye un apéndice con las versiones de las dependencias de cada versión. También puedes encontrar ahí las propiedades de versión. Estas propiedades se pueden sobrescribir tanto en Maven como en Gradle para que se use una versión más reciente de la dependencia transitiva.
En Maven, puedes agregar una propiedad en la sección de propiedades.
En Gradle, podemos editar esta propiedad en un archivo `gradle.properties`:
Esta es la opción preferida frente a la gestión de dependencias, ya que `snakeyaml` es una sola biblioteca. Sin embargo, en muchos casos hay más de una biblioteca. La versión puede hacer referencia a un BOM (lista de materiales), que no debe confundirse con un SBOM, que representa un conjunto de grupos de paquetes que deben usarse juntos y, en esencia, tener la misma versión, como un paquete de API y uno de implementación. Ambos deben tener la misma versión para funcionar según lo previsto.
Declaración de gestión de dependencias
Otra opción es usar los mecanismos de tu herramienta de compilación para actualizar las dependencias transitivas. Solo debes hacerlo si no puedes actualizar la propiedad de versión como se muestra en la sección anterior.
En Maven, lo más común es agregarlo al bloque `dependencyManagement`. Este bloque garantiza que se use la versión actualizada especificada en él cada vez que se llame a la biblioteca como dependencia transitiva.
Maven:
Como usamos el complemento dependency-management para Spring en nuestro archivo Gradle, tenemos capacidades muy similares disponibles en Gradle. Ten en cuenta que el inicializador de Spring Boot agregó este complemento al crear la estructura de mi proyecto.
Gradle:
Si no usas el complemento `io.spring.dependency-management`, también puedes agregar restricciones a las dependencias transitivas en Gradle para actualizar una dependencia transitiva como la que aparece a continuación. Recuerda que estas restricciones no funcionan bien con el complemento `dependency-management` de Spring. Por lo tanto, debes elegir una opción u otra.
Analiza tus aplicaciones Spring Boot con Snyk
Analizar tu aplicación Spring Boot con Snyk es fundamental para garantizar la seguridad y estabilidad de tu software. Snyk ayuda a identificar vulnerabilidades en las dependencias de tu aplicación que los actores maliciosos podrían aprovechar si no las corriges. Después de leer este artículo, también sabes cuál es la mejor manera de implementar las recomendaciones de corrección de Snyk.
Analizar tu base de código con regularidad permite abordar de forma proactiva los problemas de seguridad y reducir el riesgo de filtraciones de datos y otros incidentes. Asegúrate de incluir el análisis en tu flujo habitual y de saber cómo responder cuando se presente una vulnerabilidad.
A continuación, analicé mi aplicación con la Snyk CLI antes y después de corregir las vulnerabilidades. Para corregirlas, elegí actualizar la versión general de Spring Boot y actualizar la propiedad de versión específica de `snakeyaml`.
Antes:

Después:

Así que recuerda: cuando encuentres con Snyk una vulnerabilidad relacionada con una dependencia de tu aplicación Spring Boot, sigue estos pasos:
Actualiza la versión general de Spring Boot en lugar de actualizar un starter específico.
No basta con actualizar las propiedades de versión de las dependencias de Spring Boot al actualizar la versión de Spring Boot.
Usa la gestión de dependencias en Maven o Gradle para actualizar dependencias transitivas específicas.
Empieza con los desafíos de Capture the Flag
Aprende a resolver desafíos de captura la bandera con nuestro taller virtual introductorio a pedido.



