Analizar y detectar fallos de seguridad en las dependencias de Java
Escrito por
el .
java
planeta-codigo
seguridad
Enlace permanente
Comentarios
Dada la complejidad de muchas aplicaciones de software hace que estas usen gran cantidad de dependencias, muchas de proyectos de software libre o código abierto. Es muy probable que con el paso del tiempo en alguna de las dependencias de las aplicaciones se descubra un error de seguridad importante y requiera una actualización lo más pronto posible. No es posible estar completamente a salvo de estar afectado por un fallo de seguridad en el software por mucho que se intente, por este motivo la mejor estrategia es detectar proactivamente y temprana los errores de seguridad y actualizar las dependencias a nuevas versiones con el fallo corregido. Varias organizaciones identifican, definen, describen y catalogan los fallos de seguridad de forma pública en una base de datos y hay herramientas automatizadas que con las bases de datos de fallos de seguridad permiten analizar las dependencias de un proyecto. Un ejemplo ha sido el caso de la librería Log4j 2 que por su gravedad y y popularidad muchas organizaciones han estado afectadas.
Una vez desarrollada una aplicación esta entra en un modo de mantenimiento en el que se añaden nuevas funcionalidades a las existentes y se corrigen errores. La mayor parte de la vida de una aplicación es empleada en su mantenimiento con generalmente pequeños cambios incrementales. Algunas aplicaciones son empleadas durante periodos de tiempo muy largos, de lustros o décadas, que quizá ya se consideren como heredadas y en las que ya únicamente se hacen cambios en caso de errores graves.
Aunque en una aplicación heredada ya no se hagan mejoras, ni se actualicen versiones mayores de librerías otro de los motivos por los que una aplicación requiere mantenimiento es por fallos de seguridad. Con el paso del tiempo es muy posible que en una aplicación que tenga dependencias de versiones antiguas de librerías se descubran fallos de seguridad. Si es posible y dependiendo de la gravedad del fallo de seguridad descubierto y la forma de explotarlo es conveniente actualizar a la última versión de la librería o al menos a la última versión compatible con el fallo de seguridad corregido. En una aplicación heredada quizá no sea posible actualizar a la última versión ya que posiblemente por un lado requiere cambios importantes en el código y tiempo para hacerlos y por otro lado se trate de evitar hacer cambios para no introducir errores en el código que está funcionando.
Una de las formas de analizar el código fuente de una aplicación es analizar sus dependencias para conocer si en alguna de ellas se descubre alguna vulnerabilidad. Hay herramientas automatizadas que realizan las dependencias y generan un informe con las vulnerabilidades que tienen. En este caso el análisis estático de código se hace sobre las dependencias sobre el código fuente al igual que las comprobaciones que también se pueden hacer sobre el código para comprobar que cumple las convenciones, algunas restricciones y algunos fallos detectables sobre el código fuente que se pueden hacer con PMD.
Contenido del artículo
Base de datos de fallos de seguridad
Los fallos de seguridad descubiertos se identifican, definen y catalogan con un nombre y se añaden a una base de datos pública de vulnerabilidades de seguridad. Al definir los fallos de seguridad se les asigna un nivel orientativo de gravedad, dos propiedades importantes que sirven para asignar la gravedad son como es la forma de explotar el fallo de seguridad, si requiere acceso físico al sistema o es posible explotarlo de forma remota, y que permite el fallo de seguridad, como ejecución de código remoto o obtención de información confidencial.
Aunque algunos fallos de seguridad permiten la ejecución remota de código no se consideran tan importantes si requieren acceso físico al sistema. Los más graves son aquellos que concurren ambas circunstancias, permiten explotar los fallos de seguridad de forma remota y permite realizar acciones graves como ejecución de código remoto, escalar privilegios u obtener información confidencial.
Por otro lado, la organización OWASP tiene documentados fallos de seguridad comunes en las aplicaciones y que conviene evitar, por ejemplo, el error de sql injection o cross site scripting que no por ser ya muy conocidos y no complicados de evitar dejan de ser graves si la aplicación no se implementa adecuadamente.
El problema de seguridad de Log4j 2
Un caso de error grave de seguridad denominado identificado con el nivel máximo en la escala de gravedad es el de la librería Log4j 2 en las versiones menores a 2.3.2 (para Java 6), 2.12.4 (para Java 7) y 2.17.1 (para Java 8 y posteriores) que es posible explotarlo de forma remota y permite ejecución remota de código denominado Log4Shell. Log4j 2 es una librería de Java muy utilizada en los proyectos por ser una funcionalidad fundamental para cualquier aplicación que sirve para emitir trazas o logging.
Dada la gravedad del error descubierto y el amplio uso de la librería en los proyectos Java muchas organizaciones se han visto afectadas por el error de seguridad. La corrección del error requiere actualizar la versión de la dependencia de Log4j a una que no sea vulnerable al error. El problema es que muchas aplicaciones heredadas actualizar a la última versión no es posible e incluso actualizar a una versión compatible no vulnerable supone gran esfuerzo que requiere actualizar la dependencia en el código fuente, generar el nuevo artefacto, validarlo y hacer su despliegue en el entorno de producción.
Mientras se realiza la corrección conviene observar los registros de trazas, el uso de la CPU, red, memoria, almacenamiento y registros de log ante cualquier comportamiento anómalo para ver si la aplicación está siendo objeto de ataque.
Aún siendo Log4j una librería mantenida por tres personas de forma voluntaria su licencia de código abierto y alta calidad que muchas veces es mayor incluso que las opciones equivalentes comerciales es utilizada por muchas empresas incluso con facturaciones mil millonarias debido a que no necesitan pagar licencias de software para usarla. Sin embargo, no todas las empresas mil millonarias que usan un software que es vital para su negocio apoyan económicamente a esos proyectos de software que usan. Aún así, esos tres voluntarios pocas horas después de hacerse público el error con la ayuda de los interesados han publicado varias versiones de la librería con el fallo original y posteriores descubiertos corregidos.
Esta misma historia ya se repitió en el 2014 con OpenSSL con el denominado Heartbleed y se volverá a repetir con otro ejemplo en el futuro. Proyectos en los que no solo se fundamenta ya una empresa sino en los que se fundamenta internet cuyos desarrolladores trabajan de forma voluntaria sin apoyo económico.
- Tech giants, chastened by Heartbleed, finally agree to fund OpenSSL
- Of Money, Responsibility, and Pride
Analizar y detectar fallos de seguridad en las dependencias de Java con Gradle y Maven
Dado que se volverá a repetir un fallo de seguridad como Log4 2 o Heartbleed y dado que es imposible estar seguro de que una dependencia no se vea afectada en algún momento por un fallo grave de seguridad conviene estar suscrito a los boletines de seguridad y analizar las dependencias, automatizar el análisis de las dependencias es la mejor opción para que la mayor parte del trabajo lo hagan las computadoras en vez de personas y detectar los fallos de seguridad en cuanto sean publicados.
La misma organización OWASP proporciona una herramienta automatizada para comprobar la seguridad de las dependencias de un proyecto. La herramienta se usa como un complemento en las herramientas de construcción Gradle o Maven y al ejecutar las tareas que añaden analizan las dependencias y versiones del proyecto y las compara con las bases de datos de errores conocidos. El resultado es un informe con una lista de las vulnerabilidades de cada librería del proyecto si es que tienen alguna. El plugin de OWASP también detecta los fallos de seguridad en las dependencias de forma transitiva a las que se declaren en el archivo de construcción de forma explícita.
En el siguiente ejemplo de proyecto con Gradle se incluye como dependencia una versión de Log4j 2 vulnerable, con el plugin de OWASP para detectar vulnerabilidades y la tarea dependencyCheckAnalyze se identifican los CVE a los que es vulnerable cada una de las dependencias en este caso la de Log4j 2. En cada uno de los CVE y en las referencias asociadas se detalla el fallo de seguridad.
Estos son los CVE que detecta para la versión 2.14.1.
|
|
|
|
|
|
Detectado el fallo de seguridad basta con cambiar la versión de Log4j 2 a la última no vulnerable y el error desaparece del informe.
|
|
|
|
En un proyecto con Maven el análisis se realiza con el siguiente comando:
|
|
Analizar repositorios de Git
En una organización con gran cantidad de repositorios de Git un error como este supone analizar cada uno de los proyectos, para automatizar la tarea el siguiente script clona los repositorios a analizar, detecta si es un repositorio Gradle o Maven y ejecuta la tarea de análisis de las dependencias.
|
|
|
|
|
|
El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:./gradlew dependencyCheckAnalyze