sorenpoulsen.com header

Using OWASP Dependency Check with Maven

Using software components with known security vulnerabilities is a class of security risk listed at rank 9 on the OWASP Top 10 Security Risks for 2017.

A recent example is the company Equifax that suffered a massive data breach affecting more than 145 mio. people. Equifax failed to apply a security patch for the Apache Struts2 web framework for several months despite their own policy to apply patches within 48 hours.

The OWASP foundation has a free tool OWASP DependencyCheck that detects the use of vulnerable components and as we shall see in this post, it also detects the vulnerability known as CVE-2017-5638 in Apache Struts2 that was the cause of Equifax's predicament.

Integrating OWASP DependecyCheck in a software project built with Apache Maven is fairly straightforward, so let's dig in.

Add the OWASP DependecyCheck plugin to a Maven project

Add dependency-check-maven plugin to the project's pom.xml file.

Run the dependency check

Run the plugin's check goal.

$ mvn test org.owasp:dependency-check-maven:check
...
[INFO] --- dependency-check-maven:2.1.1:check (default-cli) @ TestDependencyCheck ---
[INFO] No dependencies were identified that could be analyzed by dependency-check
[INFO] Checking for updates
[INFO] starting getUpdatesNeeded() ...
[INFO] NVD CVE requires several updates; this could take a couple of minutes.
[INFO] Download Started for NVD CVE - 2003
[INFO] Download Started for NVD CVE - 2002
[INFO] Download Started for NVD CVE - 2007
[INFO] Download Started for NVD CVE - 2005
[INFO] Download Started for NVD CVE - 2004
[INFO] Download Started for NVD CVE - 2006
[INFO] Download Complete for NVD CVE - 2003  (4174 ms)
[INFO] Download Started for NVD CVE - 2008
[INFO] Processing Started for NVD CVE - 2003
[INFO] Download Complete for NVD CVE - 2004  (5513 ms)
[INFO] Download Started for NVD CVE - 2009
[INFO] Processing Started for NVD CVE - 2004
[INFO] Processing Complete for NVD CVE - 2003  (1863 ms)
[INFO] Download Complete for NVD CVE - 2005  (6441 ms)
[INFO] Download Started for NVD CVE - 2010
[INFO] Processing Started for NVD CVE - 2005
[INFO] Processing Complete for NVD CVE - 2004  (1963 ms)
[INFO] Download Complete for NVD CVE - 2007  (8092 ms)
[INFO] Download Started for NVD CVE - 2011
[INFO] Processing Started for NVD CVE - 2007
[INFO] Download Complete for NVD CVE - 2006  (8746 ms)
[INFO] Processing Started for NVD CVE - 2006
[INFO] Download Started for NVD CVE - 2012
[INFO] Processing Complete for NVD CVE - 2005  (3144 ms)
[INFO] Download Complete for NVD CVE - 2002  (11534 ms)
[INFO] Processing Started for NVD CVE - 2002
[INFO] Download Started for NVD CVE - 2013
[INFO] Download Complete for NVD CVE - 2008  (8114 ms)
[INFO] Processing Started for NVD CVE - 2008
[INFO] Download Started for NVD CVE - 2014
[INFO] Download Complete for NVD CVE - 2009  (7702 ms)
[INFO] Download Started for NVD CVE - 2015
[INFO] Processing Complete for NVD CVE - 2007  (7395 ms)
[INFO] Processing Started for NVD CVE - 2009
[INFO] Download Complete for NVD CVE - 2010  (9861 ms)
[INFO] Download Started for NVD CVE - 2016
[INFO] Processing Complete for NVD CVE - 2006  (9615 ms)
[INFO] Processing Started for NVD CVE - 2010
[INFO] Download Complete for NVD CVE - 2012  (9792 ms)
[INFO] Download Started for NVD CVE - 2017
[INFO] Processing Complete for NVD CVE - 2002  (7566 ms)
[INFO] Processing Started for NVD CVE - 2012
[INFO] Download Complete for NVD CVE - 2013  (12117 ms)
[INFO] Download Started for NVD CVE - Modified
[INFO] Download Complete for NVD CVE - 2015  (10612 ms)
[INFO] Download Complete for NVD CVE - 2014  (12614 ms)
[INFO] Download Complete for NVD CVE - 2016  (10442 ms)
[INFO] Download Complete for NVD CVE - 2011  (19551 ms)
[INFO] Download Complete for NVD CVE - Modified  (7219 ms)
[INFO] Download Complete for NVD CVE - 2017  (13710 ms)
[INFO] Processing Complete for NVD CVE - 2009  (17274 ms)
[INFO] Processing Started for NVD CVE - 2013
[INFO] Processing Complete for NVD CVE - 2008  (21717 ms)
[INFO] Processing Started for NVD CVE - 2015
[INFO] Processing Complete for NVD CVE - 2010  (23019 ms)
[INFO] Processing Started for NVD CVE - 2014
[INFO] Processing Complete for NVD CVE - 2012  (24867 ms)
[INFO] Processing Started for NVD CVE - 2016
[INFO] Processing Complete for NVD CVE - 2013  (21390 ms)
[INFO] Processing Started for NVD CVE - 2011
[INFO] Processing Complete for NVD CVE - 2015  (25555 ms)
[INFO] Processing Started for NVD CVE - Modified
[INFO] Processing Complete for NVD CVE - 2014  (36331 ms)
[INFO] Processing Started for NVD CVE - 2017
[INFO] Processing Complete for NVD CVE - 2016  (37048 ms)
[INFO] Processing Complete for NVD CVE - Modified  (33684 ms)
[INFO] Processing Complete for NVD CVE - 2011  (40076 ms)
[INFO] Processing Complete for NVD CVE - 2017  (17620 ms)
[INFO] Begin database maintenance.
[INFO] End database maintenance.
[INFO] Check for updates complete (101670 ms)
[INFO] Analysis Started
[INFO] Finished File Name Analyzer (0 seconds)
[INFO] Finished Central 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 (2 seconds)
[INFO] Finished False Positive Analyzer (0 seconds)
[INFO] Finished Cpe Suppression Analyzer (0 seconds)
[INFO] Finished NVD CVE Analyzer (0 seconds)
[INFO] Finished Vulnerability Suppression Analyzer (0 seconds)
[INFO] Finished Dependency Bundling Analyzer (0 seconds)
[INFO] Analysis Complete (2 seconds)

The plugin downloads all the known Common Vulnerabilities and Exposures (CVE) records from the National Vulnerability Database (NVD) and stores them in the Maven repository under /.m2/repository/org/owasp/dependency-check-data/3.0/dc.h2.db.

It then proceeds to analyze the Maven project's dependencies. All vulnerable dependencies are listed directly in the console output.

On subsequent runs the plugin will only download updates from NVD.

The project's pom.xml shown previously doesn't have any dependencies other that the plugin itself. To spice things up let's add Apache Struts2 version 2.5.10 as a dependency in our project.

Run the dependency checker again.

$ mvn test org.owasp:dependency-check-maven:check
...
[WARNING] One or more dependencies were identified with known vulnerabilities in TestDependencyCheck:

commons-fileupload-1.3.2.jar (commons-fileupload:commons-fileupload:1.3.2, cpe:/a:apache:commons_fileupload:1.3.2) : CVE-2016-1000031
log4j-api-2.7.jar (cpe:/a:apache:log4j:2.7, org.apache.logging.log4j:log4j-api:2.7) : CVE-2017-5645
struts2-core-2.5.10.jar (cpe:/a:apache:struts:2.5.10, org.apache.struts:struts2-core:2.5.10) : CVE-2017-9805, CVE-2017-9804, CVE-2017-9793, CVE-2017-9787, CVE-2017-7672, CVE-2017-5638, CVE-2017-12611

This time the dependency checker detects multiple vulnerabilities, including CVE-2017-5638 which is a Remote Code Execution vulnerability.

The OWASP DependencyCheck report

We could google each CVE, but the dependency checker has already prepared a report with all the details, stored in target/dependency-check-report.html.

screenshot of OWASP DependencyCheck report

Scroll to the Struts2 vulnerability CVE-2017-5638.

screenshot of OWASP DependencyCheck report

Because it's a Remote Code Execution vulnerability that can be used without being authenticated it rightly deserves the highest possible CVSS score of 10.0.

Remote Code Execution opens up a plethora of ways to backdoor a system. Here are some commen cookie cutter backdoors:

a. An attacker executes code on the server that starts a new operating system shell process and links it up with a Servlet by piping commands from HTTP requests through to the shell. Output from the shell is piped back to the Servlet and returned as an HTTP response. This type of backdoor is typically used for further privilege escalation in the server's operating system and beyond.

b. An attacker executes code on the server that downloads and writes a specially crafted backdoor.jsp to the hot deployment folder on the server. It's active right away, no server restart required. The JSP page shows a menu to scan files and directories on the server, upload and download files. This type of backdoor is often used to turn the web server into a malware spreading site.

False positives

The dependency checker detects the use of known vulnerabilities by looking for matches of the dependencies in the Maven project with the software components listed in the CVEs. This process is a little sketchy because they have different schemes for identifying software. Maven identifies dependencies using GroupId, ArtifactId and Version (GAV) and CVEs identify software using Common Platform Enumeration (CPE).

Scrolling back to the list of vulnerable dependencies we find a column named CPE Confidence. This is a score of how confident the dependency checker is that it made a correct match.

In the case of the Struts2-core-2.5.10.jar dependency the CPE Confidense is "Highest". To any human being reading the description it is obvious that this is indeed a match but we will often have false positives. So regardless of the CPE Confidense it is always prudent to read through the CVE description and make our own conclusions.

To prevent false positives from reappearing we can suppress either the software component identified by the CPE or the individual vulnerability by clicking the Suppress button in the report and saving the XML snippet to a file in the project. The first time select the output from "Complete XML Doc". Say we stored the XML in the root of the Maven project in a file named suppressed.xml we would then configure the dependency checker to use this file using the suppressionFiles option in the pom.xml.

Activating the dependency checker with a Maven profile

It's easier to activate the plugin with a Maven profile. In this example the profile is named securitycheck.

Use the -P option to activate the profile.

$ mvn clean install -Psecuritycheck

Fail the build when vulnerabilities are detected

To make sure detected vulnerabilities don't go unnoticed we could set up an automated Jenkins job to run the dependency checker regularly and configure the plugin to fail the build when vulnerabilities are detected.

The following pom.xml fails on any vulnerability by setting the configuration property failBuildOnAnyVulnerability to true. Alternatively we could use the failBuildOnCVSS to fail on a CVSS score above a certain threshold.

{{model.usr.name}}
{{cmt.user.name}}
{{cmt.user.name}}
{{childcmt.user.name}}
{{childcmt.user.name}}