Friends of OpenJDK Today

Fixing Vulnerabilities in Maven Projects

October 20, 2020

Author(s)

  • Avatar photo
    Brian Vermeer

    Java Champions & Developer Advocate and Software Engineer for Snyk. Passionate about Java, (Pure) Functional Programming, and Cybersecurity. Co-leading the Virtual JUG, NLJUG and DevSecCon community. Brian is also an ... Learn more

Maven is still the most used build system in the Java ecosystem. According to the JVM report 2020, Maven is the number one build tool in the ecosystem with two-thirds of the share. 

Therefore, it is important to know how Maven works. For instance, if you find vulnerabilities in your Maven project using Snyk, how can you fix them? 

In this article, I will explain how you can fix vulnerabilities in third-party libraries when using Maven, even when it is not obvious.

Finding vulnerabilities

If you are using Maven for building your project and managing your dependencies for your project, there are several ways to scan your projects, using tools such as Snyk. This is regardless of the actual programming language you use—this can be Java, Kotlin, Scala, Groovy, or any other language that is designed for the Java Virtual Machine (JVM).

Scanning your Maven project for vulnerabilities can be done, by using Snyk, for example. In the example below, I use the Snyk CLI, which will show you if and how you can fix vulnerabilities, by updating the top-level dependencies. However, if there is no improved version of the top-level dependencies, Snyk shows you if there is a newer version of the underlying dependency that fixes the vulnerabilities.

Fixing top-level vulnerabilities 

The easiest way to fix a vulnerability found by Snyk is to change the top level library, if possible. If the library does not have underlying dependencies it is quite obvious that you need to upgrade to a newer version that does not have that particular issue. The same applies when an underlying dependency does have an issue but there is already a newer version of the top-level dependency available that doesn’t have the issue.

There are a few ways to switch the version.
First, find out where the version is specified. For top-level dependencies, in most cases, you can find it in one of the following:

  • in a parent pom
  • in a property
  • direct at the dependency level

Parent POM

If the dependency you need to upgrade is defined in a parent pom, first look for a newer version of the parent pom. Take Spring Boot for instance, if there already is a newer version of the parent, consider upgrading to that newer version first and see if that solves the problem. This way you update the whole set of dependencies and, in most cases, they play along better than just upgrading a single dependency. If you cannot switch or change the parent, jump to the direct approach.

<parent>
   <groupId>io.foojay</groupId>
   <artifactId>demo-parent</artifactId>
   <version>1.0.4.RELEASE</version>
</parent>

Properties

If a property is used, update the property first. This can potentially update other dependencies as well, but just as with the parent pom, there is a good reason for this. If libraries are released as a set you know that they work better together if they have the same version.

<properties>
    <commons-lang3.version>3.9</commons-lang3.version>
</properties>

Direct

Finally, your dependency is declared in the dependencies part of your maven pom file. Here, you specify the groupId, artifactId, and in many cases the version. If the version is declared here, simply update it. If not, you can add it. 

Note that this is the lowest level of declaring the dependency version and will override all the other ways of setting the version.

<dependency>
  <groupId>org.eclipse.collections</groupId>
  <artifactId>eclipse-collections</artifactId>
  <version>10.4.0</version>
</dependency>

Fixing underlying dependencies

Let’s say there is not yet a newer version of your top-level dependency available but one of the underlying dependencies has an issue you need to fix. The CLI already notified you that there is a newer version of that underlying dependency available that fixes the problem. 

Bill of Materials

Many frameworks use a Bill of Materials (BOM) to manage underlying dependencies. A BOM is a special kind of POM that is used to control the versions of a project’s dependencies and provide a central place to define and update those versions. 

When an underlying dependency needs to be replaced in a framework like Spring Boot, take a look if this dependency is part of the BOM. If so, check if there already is a newer version of that specific BOM and update the version. In Spring Boot and many other well-known frameworks, the versions of the BOM are specified as a property. You can override the property in your own Maven POM file by adding a property.

In the example below, I override the BOM for Jackson in my Spring Boot project:

<properties>
    <jackson.version>2.10.2.20200130</jackson.version>
</properties>

Dependency management

In a Maven POM, it is possible to exclude and include specific underlying dependencies when declaring a top-level dependency. However, this can be problematic when two libraries share the same underlying dependency. A best practice in Maven is to bundle these declarations in the dependency management section. This section allows project authors to directly specify the versions of artifacts to be used when they are encountered in transitive dependencies. In addition to the example below, the documentation clearly explains how dependencyManagement should be used:

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>org.yaml</groupId>
           <artifactId>snakeyaml</artifactId>
           <version>1.26</version>
       </dependency>
   </dependencies>
</dependencyManagement>


Conclusion

As you can see, there are several ways to mitigate security issues in open source dependencies for a Maven-based project.

Even when there is no direct fix by updating a top-level dependency, you are able to filter out an underlying transitive dependency and switch to the newer available version.

Snyk open source scanning provides you with information on what version you need to upgrade. This article shows you how you can configure it properly in your Maven project.

Related Articles

View All

Author(s)

  • Avatar photo
    Brian Vermeer

    Java Champions & Developer Advocate and Software Engineer for Snyk. Passionate about Java, (Pure) Functional Programming, and Cybersecurity. Co-leading the Virtual JUG, NLJUG and DevSecCon community. Brian is also an ... Learn more

Comments (0)

Your email address will not be published. Required fields are marked *

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard