Checking framework vulnerabilities using Dependency Check

A web-application is never finished. Even when no new features are being developed new vulnerabilities may be found in the frameworks used in the application requiring a patch or an upgrade. Are you actively monitoring the frameworks that are in use in your applications? My guess is no, or at least not all of them. Well, luckily enough OWASP has a very nice utility that easily integrates into a build environment and can do most of the hard work for you. Let me tell you about it.



The utility is called Dependency Check and is written and maintained by Jeremy Long. It comes in four different flavors: a Maven plugin, an Ant task, a commandline script and a Jenkins (build server) plugin. In this blog post I will focus on the maven plugin.



Integrating Dependency Check into the Maven build



Making the Dependency Check plugin a part of the Maven build is easy. It involves declaring the plugin as a part of your build and naming the goal to run (there is only one, check).




<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
</plugin>


There are several configuration options but we'll look into that later. First, lets run the build and see what happens:




[INFO] --- dependency-check-maven:1.2.1:check (default) @ someproject ---
Jun 15, 2014 1:37:15 PM org.owasp.dependencycheck.data.update.StandardUpdate update
INFO: NVD CVE requires several updates; this could take a couple of minutes.
Jun 15, 2014 1:37:15 PM org.owasp.dependencycheck.data.update.task.CallableDownloadTask call
INFO: Download Started for NVD CVE - 2002
Jun 15, 2014 1:37:15 PM org.owasp.dependencycheck.data.update.task.CallableDownloadTask call
INFO: Download Started for NVD CVE - 2003
Jun 15, 2014 1:37:15 PM org.owasp.dependencycheck.data.update.task.CallableDownloadTask call
INFO: Download Started for NVD CVE - 2004


Ok, this could take a while. Dependency Check tests against the 'National Vulnerability Database' (NVD) which holds known vulnerabilities of software products. Dependency Check will download the whole NVD once and stores it in your local maven repository. Each subsequent run checks for updates. After that comes the analysis:




Jun 15, 2014 1:43:16 PM org.owasp.dependencycheck.Engine analyzeDependencies INFO: Analysis Starting
Jun 15, 2014 1:46:52 PM org.owasp.dependencycheck.Engine analyzeDependencies INFO: Analysis Complete
Jun 15, 2014 1:46:54 PM org.owasp.dependencycheck.maven.DependencyCheckMojo showSummary WARNING:


One or more dependencies were identified with known vulnerabilities:




commons-fileupload-1.2.2.jar
(commons-fileupload:commons-fileupload:1.2.2, cpe:/a:apache:commons_fileupload:1.2.2) :
CVE-2014-0050, CVE-2013-0248
javax.servlet.jsp.jstl-1.2.1.jar
(cpe:/a:oracle:glassfish, cpe:/a:oracle:glassfish_server:1.2.1) :
CVE-2013-2566, CVE-2011-5035


Oh dear. It seems that my project is vulnerable! The console lists only the summary, a report containing full details are present in ./target/dependency-check-report.html



How does Dependency Check work?



Interestingly enough its current version (1.2.1) doesn't (yet) use the version information available inside the Maven pom. Instead it relies on the contents of the META-INF folder present in most jars or alternatively it looks up the name and version in Sonatype Nexus Repository using the hash of the jar file. It then uses that information to form the so called 'Common Platform Identifier' (CPI) and uses that to find vulnerabilities in the NVD downloaded before the analysis.



Vulnerabilities are named using a 'Common Vulnerabilities and Exposures' (CVE) identifier and contain the most important information on a vulnerability. Have a look at one. Note how each entry has a severity score which, on a scale from 1 to 10, indicates how bad the issue is. A score of 7 to 10 indicates a critical flaw. You need to know that this rating means of course, for example the recent HeartBleed bug in OpenSSL 'only' scored 5.0. Notice the nice red explanation on the why of this 'low' score. Yes, the score only evaluates the direct risk to the system having the vulnerability.



The NVD database combined with the CPI results in one or more CVE identifiers if your libraries contain known vulnerabilities. By default this doesn't break the build, but you can make it by specifying a highest allowed severity score (using failBuildOnCVSS) in the configuration.



Dependency Check results



Let's investigate why Dependency Check found some of my jars vulnerable. Lets start with commons-fileupload. CVE-2014-0050, CVE-2013-0248 tell me that my version of this library allows for a denial of service attack and the overwriting of arbitrary files. Not good! I definitely need to upgrade this library.



The other library, the Java standard Tag Library has two CVE's that seem rather odd for its function (CVE-2013-2566, CVE-2011-5035). The first complains about encryption and the RC4 algorithm. The second is about Hash Collisions. Both seem to be talking about application servers, not a Tag library. If you look at the console output you can see that the library was wrongly identified as oracle:glassfish_server:1.2.1



False Positives



Because of often incomplete data in the META-INF folder and that not all jar files are in the Sonatype Nexus some jars cannot be identified (such as most of the spring-framework jars) or are wrongly identified (e.g. the jstl jar). This means that sometimes vulnerabilities are missed or incorrectly reported. Fortunately Dependency Check has a suppression file which is an easy to fill XML document to suppress false positives (the resulting html report has a button to generate xml snippets for easy copy and pasting). Configuring a suppression file is easy:




<configuration>
<suppressionFile>ignore.xml</suppressionFile>
</configuration>


And the suppression file itself, with snippets generated by the html report:




<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
<suppress>
<notes><![CDATA[file name: javax.servlet.jsp.jstl-1.2.1.jar]]></notes>
<sha1>7F687140E9D264EE00EAA924714ADF9A82CC18DC</sha1>
<cve>CVE-2013-2566</cve>
</suppress>
<suppress>
<notes><![CDATA[file name: javax.servlet.jsp.jstl-1.2.1.jar]]></notes>
<sha1>7F687140E9D264EE00EAA924714ADF9A82CC18DC</sha1>
<cve>CVE-2011-5035</cve>
</suppress>
</suppressions>


When the the dependency check is ran now, these two vulnerabilities will no longer be listed for this file.



My guess is that when Dependency Check will start using the dependency information from the maven pom most of these false positives will be history :-)



False Negatives



Currently Dependency Check is unable to identify all libraries (because of missing metadata and presence in the Sonatype Nexus) - these libraries (easily recognized by the lack of an Identifier in the report) still need manual investigation. Again, the dependency information from the maven pom will reduce these.



Performance



If you look at the timestamps present in my analysis phase you'll will see that the whole check takes about 3 minutes. This time is mostly spent in talking to the Sonatype Nexus repository, trying to find the version information for the hash of the jar file. This feature can be disabled (you'll loose identification of some jars) by disabling the Nexus analyzer in the configuration file:



<nexusAnalyzerEnabled>false</nexusAnalyzerEnabled>


The check now only takes 10 seconds or so. Of course there is no need to check the dependencies for vulnerabilities each time you make a build. A check once a day is more than sufficient. The ideal place to me it seems is the nightly build on the continuous integration server (e.g. Bamboo, Jenkins) - most of the time these builds use a separate profile to which the dependency check plugin can be added without interfering with the developer build. Also perform the check before making a new release of your application.



Summary and recommendations



OWASP Dependency Check is a valuable tool that warns you when you've got outdated libraries with known vulnerabilities as part of your project.



Currently Dependency Check uses meta data in the library to identify it or looks up the file hash in the Sonatye Nexus. Sometimes this results in a incorrectly identified library with false positives being reported. These are easily suppressed using a suppression file. Also if a library cannot be identified at all, dependency check may not report an vulnerability. However, in an upcoming version support for the dependencies in the Maven pom will be included. My guess is that the amount of false positives and false negatives will be greatly reduced.



I think Dependency Check is best used as part of the nightly build on the continuous integration server and just before a making a release.