OWASP Dependency Check Maven Plugin

Publicado por Arturo García Martín el

Arquitectura de SolucionesOWASPDependency CheckMavenPlugin

Introducción

La reciente detección de una vulnerabilidad asociada al popular Log4J ha puesto de relieve la necesidad de estar al día, en cuanto a cuestiones de seguridad se refiere.

Dependency Check Report

Una de las herramientas que pueden ayudar a los desarrolladores (sobre todo en aquellos proyectos basados en Spring boot) a detectar y corregir este tipo de situaciones es el OWASP Dependency Check Maven Plugin.

Y, como cualquier otro plugin Maven, este también se encuentra disponible en Maven Central.

Ejemplo de uso

Para entender el funcionamiento de este plugin, vamos a plantear un ejemplo simple a partir de Spring boot.

Como ejemplo, vamos a tomar el que nos muestra Spring en esta página o en esta otra; la idea es ver el plugin OWASP en ejecución, no en crear un microservicio.

Una vez que hemos instalado y ejecutado nuestro proyecto Spring boot en local, tal como se indican en las páginas anteriores, veamos cómo podemos aprovecharnos del OWASP Dependency Check Maven Plugin .

En primer lugar, hay que incorporar al archivo pom.xml, de Maven, el código relacionado con el plugin.

<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.atsistemas.devsecops</groupId>
    <artifactId>sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Sample</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!-- OWASP Dependency Check Maven Plugin. -->
            <plugin>
                <groupId>org.owasp</groupId>
                <artifactId>dependency-check-maven</artifactId>
                <version>6.5.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>  

A continuación, procedemos a ejecutar el siguiente comando Maven.

mvn org.owasp:dependency-check-maven:check  

( NOTA: Hacemos esto porque el plugin está ligado a la fase: verify de Maven y, de esta otra manera, lo ejecutamos cuando queramos. )

La primera ejecución, como es normal, conlleva la descarga tanto de los archivos propios del plugin como la de los archivos de datos necesarios para las comprobaciones de seguridad. Es por esto por lo que esta primera ejecución conlleva más tiempo de lo normal.

Si, por la razón que sea, en este momento o en otra ocasión, nos surge algún tipo de error relacionado con el componente "RetireJS" o con la descarga de la base de datos, no nos preocupemos; nada tan sencillo como relanzar el comando de nuevo.

La base de datos de vulnerabilidades ya se nos habrá descargado en la ruta:

[PATH_TO_MAVEN_LOCAL_REPOSITORY]\.m2\repository\org\owasp\dependency-check-data\5.0

( NOTA: La base de datos se descarga desde: https://cve.mitre.org/data/downloads/index.html. )

El resultado de la ejecución de este comando Maven debería ser similar al siguiente.

[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< com.atsistemas.devsecops:sample >-------------------
[INFO] Building Sample 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- dependency-check-maven:6.5.3:check (default-cli) @ sample ---
[INFO] Checking for updates
[INFO] Skipping NVD check since last check was within 4 hours.
[INFO] Skipping RetireJS update since last update was within 24 hours.
[INFO] Check for updates complete (861 ms)
[INFO] 

Dependency-Check is an open source tool performing a best effort analysis of 3rd party dependencies; false positives and false negatives may exist in the analysis performed by the tool. Use of the tool and the reporting provided constitutes acceptance for use in an AS IS condition, and there are NO warranties, implied or otherwise, with regard to the analysis or its use. Any use of the tool and the reporting provided is at the user?s risk. In no event shall the copyright holder or OWASP be held liable for any damages whatsoever arising out of or in connection with the use of this tool, the analysis performed, or the resulting report.  
   About ODC: https://jeremylong.github.io/DependencyCheck/general/internals.html
   False Positives: https://jeremylong.github.io/DependencyCheck/general/suppression.html

? Sponsor: https://github.com/sponsors/jeremylong
[INFO] Analysis Started
[INFO] Finished Archive Analyzer (0 seconds)
[INFO] Finished File Name Analyzer (0 seconds)
[INFO] Finished Jar Analyzer (0 seconds)
[INFO] Finished Dependency Merging Analyzer (0 seconds)
[INFO] Finished Version Filter Analyzer (0 seconds)
[INFO] Finished Hint Analyzer (0 seconds)
[INFO] Created CPE Index (2 seconds)
[INFO] Finished CPE Analyzer (3 seconds)
[INFO] Finished False Positive Analyzer (0 seconds)
[INFO] Finished NVD CVE Analyzer (0 seconds)
[INFO] Finished Sonatype OSS Index Analyzer (1 seconds)
[INFO] Finished Vulnerability Suppression Analyzer (0 seconds)
[INFO] Finished Dependency Bundling Analyzer (0 seconds)
[INFO] Analysis Complete (8 seconds)
[INFO] Writing report to: [PROJECT_FOLDER]\target\dependency-check-report.html
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  15.253 s
[INFO] Finished at: 2022-01-19T11:14:40+01:00
[INFO] ------------------------------------------------------------------------

Si nos fijamos con atención, tras ejecutar el comando nos indica, al final, que se ha generado un "report" en la ruta: "[#PROJECT_FOLDER#]\target\dependency-check-report.html".

Si abrimos este archivo, deberíamos ver algo muy similar a lo que se muestra en la siguiente imagen.

Dependency Check Report

Como podemos apreciar, aunque podamos hacer click en el enlace: "Showing Vulnerable Dependencies (click to show all)" y mostrar todas las vulnerabilidades encontradas (y que se deberían resolver, lógicamente ;^)), principalmente, no aparece ninguna "relevante". Las "relevantes" se muestran en la tabla inferior.

Para ver un ejemplo de esto, vamos a incorporar la dependencia de Log4J (una de las afectadas por la vulnerabilidad, se entiende) en nuestro pom.xml, y veremos qué ocurre.

Al estar trabajando con Sping boot, podemos poner en el archivo Maven "pom.xml" la siguiente dependencia.

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>

o simplemente decirle a Spring boot que coja una dependencia de versión previa; así:

    <properties>
        <!-- ... otras... -->
        <log4j2.version>2.12.0</log4j2.version>
    </properties>

y volvemos a ejecutar el comando Maven anterior.

mvn org.owasp:dependency-check-maven:check  

El resultado, en consola, es:

[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< com.atsistemas.devsecops:sample >-------------------
[INFO] Building Sample 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- dependency-check-maven:6.5.3:check (default-cli) @ sample ---
[INFO] Checking for updates
[INFO] Skipping NVD check since last check was within 4 hours.
[INFO] Skipping RetireJS update since last update was within 24 hours.
[INFO] Check for updates complete (758 ms)
[INFO] 

Dependency-Check is an open source tool performing a best effort analysis of 3rd party dependencies; false positives and false negatives may exist in the analysis performed by the tool. Use of the tool and the reporting provided constitutes acceptance for use in an AS IS condition, and there are NO warranties, implied or otherwise, with regard to the analysis or its use. Any use of the tool and the reporting provided is at the user?s risk. In no event shall the copyright holder or OWASP be held liable for any damages whatsoever arising out of or in connection with the use of this tool, the analysis performed, or the resulting report.  
   About ODC: https://jeremylong.github.io/DependencyCheck/general/internals.html
   False Positives: https://jeremylong.github.io/DependencyCheck/general/suppression.html

? Sponsor: https://github.com/sponsors/jeremylong
[INFO] Analysis Started
[INFO] Finished Archive Analyzer (0 seconds)
[INFO] Finished File Name Analyzer (0 seconds)
[INFO] Finished Jar Analyzer (0 seconds)
[INFO] Finished Dependency Merging Analyzer (0 seconds)
[INFO] Finished Version Filter Analyzer (0 seconds)
[INFO] Finished Hint Analyzer (0 seconds)
[INFO] Created CPE Index (2 seconds)
[INFO] Finished CPE Analyzer (4 seconds)
[INFO] Finished False Positive Analyzer (0 seconds)
[INFO] Finished NVD CVE Analyzer (0 seconds)
[INFO] Finished Sonatype OSS Index Analyzer (1 seconds)
[INFO] Finished Vulnerability Suppression Analyzer (0 seconds)
[INFO] Finished Dependency Bundling Analyzer (0 seconds)
[INFO] Analysis Complete (8 seconds)
[INFO] Writing report to: [PROJECT_FOLDER]\target\dependency-check-report.html
[WARNING] 

One or more dependencies were identified with known vulnerabilities in Sample:

log4j-1.2.14.jar (pkg:maven/log4j/log4j@1.2.14, cpe:2.3:a:apache:log4j:1.2.14:*:*:*:*:*:*:*) : CVE-2019-17571, CVE-2020-9488, CVE-2021-4104  
See the dependency-check report for more details.  
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  16.813 s
[INFO] Finished at: 2022-01-19T11:15:42+01:00
[INFO] ------------------------------------------------------------------------

Como vemos, hay una "ligera y apreciable" diferencia.

El archivo con el informe luce ahora como en la siguiente imagen.

Dependency Check Report with Log4J vulnerability

Consideraciones Finales

Por un lado hemos de hacer notar que la incorporación de este plugin a nuestro proyecto hace que este "goal" se ejecute durante la fase Maven "install". Por eso lo ejecutamos "a mano", para forzar su ejecución manualmente cuando deseemos.

Por otra parte, ejecutar este plugin/goal a voluntad nos permite revisar y corregir, si fuera el caso, las posibles vulnerabilidades (al menos, las consideradas más relevantes) ANTES DE remitir el proyecto al repositorio GIT (si trabajamos en un equipo) y/o lo enviamos a una herramienta de Integración Continua, como Hudson o Jenkins.

Gracias a este sencillo paso, podemos dar un paso más en lo que se refiere a la seguridad de nuestro código.

Y en local. ;^)

¡Síguenos en Twitter para estar al día de próximas entregas!