Automatic checks for vulnerabilities in Java project dependencies

Security is a difficult topic to control for software projects, as is proven by the constant reports of data leaks in the media. For software developers, it is difficult to oversee the sort of influence that their daily work, which is not directly linked to security issues, has on the security of their applications.

The original article from the magazine “Java aktuell” is available here for download.

The Open Web Application Security Project (OWASP), a non-profit organisation which aims to improve web security, provides a Top Ten of the most common security problems. It shows that code written by someone else can also contain vulnerabilities. This, however, can be checked in just a few steps. The article shows how you can easily keep up to date with at least the publicly known vulnerabilities in third-party code.

The approach shown here bases on the National Vulnerability Database (NVD), a database for security vulnerabilities. The database is maintained by the National Institute of Standards and Technology (NIST), an American federal agency, which also standardises well-known encryption algorithms such as DES and AES.

The NVD contains the weaknesses recorded in the industry standard “Common Vulnerabilities and Exposures” (CVE), among others. The OWASP offers an application that checks JAR files with the NVD automatically. This so-called “OWASP Dependency-Check” (DChck) has been implemented for command lines as well as for Ant, Maven, Gradle, SBT, Jenkins and SonarQube.

The following text shows a solution concept to regularly scan Java application dependencies for new security vulnerabilities using Maven and Jenkins. Once set-up there is no need for any further steps. Information on newly discovered security vulnerabilities is then provided via e-mail. This could either contain information on newly discovered security vulnerabilities in existing dependencies or already known security vulnerabilities in newly added dependencies.

First step: Using Maven plug-in without configuration

An initial dependency check of the application can be initiated in just a few seconds without further configuration using the Maven plug-in (MVN) by executing this maven goal mvn org.owasp:dependency-check-maven:1.4.0:aggregate.
Note that the dependency-check-maven-plug-in first downloads a local copy of the CVE database as an H2 database and saves it in the local Maven repository. This results in a file containing several hundred megabytes due to the number of known security vulnerabilities. Depending on available bandwidth and computing power, the initial creation could take a few minutes. Once successfully completed, the report is found under target/dependency-check-report.html. You can find an example of such a report on the project website.

Automation with Jenkins

In order to be informed about newly found security vulnerabilities in your project without further assistance, a regular automatic check is self-evident. The OWASP offers a plug-in for the Jenkins CI-server which can carry out checks and evaluate the results. The found security vulnerabilities can be viewed in Jenkins, job results can be set depending on the number of found security vulnerabilities and the trend of the number of found security vulnerabilities for a job can be represented in a diagram. This evaluation is configured in a post build action in the Jenkins job. The dependency check itself can be completed through a build step provided by the Jenkins plug-in or via Maven.
As the check can take some time, it should not be done for each commit/push. A nightly build or a build carried out once a week is therefore appropriate. An advantage of running checks with Maven Goal instead of Jenkins Build Step is that the central configuration is done in the pom.xml, as shown in listing 1.

<properties>
    <dependency-check-format>HTML</dependency-check-format>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>org.owasp</groupId>
            <artifactId>dependency-check-maven</artifactId>
            <version>1.4.0</version>
            <configuration>
                <format>${dependency-check-format}</format>
            </configuration>
        </plugin>
    </plugins>
</build>

Listing 1: Maven configuration with customisable report format

Only the following Maven Goals must be executed with parameters in Jenkins with this configuration:
mvn clean install org.owasp:dependency-check-maven:check -Ddependency-check-format=XML.
In doing so, a target/dependency-check-report.xml file is generated in the workspace which can be processed by a corresponding post build action. Finally, the job must be configured to fail or become unstable as soon as a security flaw is discovered (see figure). With the help of Jenkins e-mail notifications, you can be sure to be notified of any new security flaw via e-mail and without any further assistance.

Practice

To end there are still a few details that could be relevant to daily work with the Dependency-Check.

It is recommended to run the Dependency-Check in the Maven module that creates the published artefact (.jar, .war, .ear etc.). This will mean that only the relevant dependencies will be checked for security vulnerabilities and not the dependencies of modules that are only used in tests. Dependencies in the Maven scope test are not checked by default in the current version of the Maven plug-in. Dependencies in the provided and runtime scopes, however, are checked by default. This behaviour can be unwanted particularly for the provided scope. If, for example, due to the customer environment you are bound to a certain servlet API, you are powerless against the security vulnerabilities contained within. In this respect it can be useful to exclude this scope. This can be adjusted in the Maven configuration (see listing 2).

Alternatively, you can suppress certain CVEs even for individual dependencies. These are defined in a special file. The XML-code for suppression can be copied directly from the HTML report created in the first step. This can be particularly useful for false positives, that is, security vulnerabilities that are not applicable to the dependency. An example for this is the general suspicion of CVE-2016-3270 against all Jackson framework modules, although a security flaw only occurs in one of them. It is therefore generally useful to check each found security flaw for correctness. In each case it should be explained as to why a CVE has been suppressed in order to be able to understand the reasons for the exclusion at a later point in time. The possibility for this exclusion is shown in listings 2 and 3.

<configuration>
    <!-- Skip artifacts not bundled in distribution (provided scope) -->
    <skipProvidedScope>true</skipProvidedScope>
    <!-- Suppress false positives or dependencies that cannot be changed for specific reasons.-->
    <suppressionFile>suppress-cves.xml</suppressionFile>
</configuration>

Listing 2: Maven configuration with suppressionFile and provided scope

<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
    <suppress>
        <!-- This Jackson-related issue seems to be related to module jackson-dataformat-xml, which is not used here. It is considered a false positive. See https://github.com/jeremylong/DependencyCheck/issues/517 In addition it was fixed in version 1.7.4., see https://github.com/FasterXML/jackson-dataformat-xml/issues/199 -->
        <notes><![CDATA[file name: jackson-core-2.8.1.jar]]></notes>
        <sha1>fd13b1c033741d48291315c6370f7d475a42dccf</sha1>
        <cve>CVE-2016-3720</cve>
    </suppress>
    <suppress>
        <!-- Same as other Jackson-related issue -->
        <notes><![CDATA[file name: jackson-annotations-2.8.0.jar]]></notes>
        <sha1>45b426f7796b741035581a176744d91090e2e6fb</sha1>
        <cpe>cpe:/a:fasterxml:jackson:2.8.0</cpe>
    </suppress>
</suppressions>

Listing 3: Example suppressionFile

Conclusion

The article describes how you can stay informed permanently about security vulnerabilities for dependencies in just a few steps. This does not guarantee absolute security but it does help to get rid of one of the ten most common security flaws with minimal effort. This is why it is recommended for all Java projects.
The Maven and Jenkins-based solution described here provides one possibility for discovering security vulnerabilities. Due to the many available implementations of the OWASP Dependency-Check, it can be used to find similar solutions for many other tools.
A complete executable example containing the aforementioned cases as well as a dependency with a non-excluded security flaw, can be found at GitHub.

Share this article

Johannes Schnatterer
Solution Architect
With a special focus on quality, open source enthusiasm, a touch of pedantry and Boy Scout Rule under his belt, he is trying to make the world of IT a little better every day.