Whether you are a software developer or not, but work in an IT company, it is very likely that you have repeatedly heard the term Log4j and the vulnerabilities that have been found in this library in the last few days.

Well, this is just one example that secure software does not exist, and that every now and then alarm bells go off due to a critical vulnerability affecting thousands of computer systems. However, there are many other libraries that are used in any software development project and that may contain very dangerous vulnerabilities.

This is something we cannot avoid, but what we can do is to minimize the risk and anticipate the possible consequences that may occur. To do this, it is very important to keep all dependencies updated to their latest version, as they are constantly being updated not only to include new features, but also to correct security problems.

Introducing OWASP

Fortunately, there is an organization called OWASP (Open Web Application Security Project) which basically aims to help the developer community to design secure software, and keep the projects as protected as possible. They don’t only promote best practices and training courses, but they also offer tools that we can include in our projects which can save us a lot of work.

Today I want to introduce a tool that I include in all my projects and is very useful to detect vulnerabilities in the software, even before putting it into production. This tool is called Dependency Check, and basically performs a scan over the entire dependency tree of our projects looking for known vulnerabilities. In case it finds any, it will generate a report that will help us to identify them so we will know which dependency includes it, and therefore how to act in order to mitigate it.

It is available for both Maven and Gradle projects. In this case, I’ll be using Maven, so you just need to include it in your pom file:

<build>
  <plugins>
    <plugin>
      <groupId>org.owasp</groupId>
      <artifactId>dependency-check-maven</artifactId>
      <version>6.5.0</version>
      <configuration>
        <failBuildOnCVSS>7</failBuildOnCVSS>
	<suppressionFiles>
	  <suppressionFile>owasp-dependency-check-suppressions.xml</suppressionFile>
	</suppressionFiles>
      </configuration>
    </plugin>
  </plugins>
</build> 


There are some important aspects inside the configuration block:

  • failBuildOnCVSS: The CVSS is basicaly the score of the vulnerability. It is a value between 0 and 10 and the higher this value is, the more dangerous the vulnerability is.
  • suppressionFile: This plugin allows us to “ignore” a vulnerability in case we don’t want/need to fix it in a short term. We should avoid using this but I will show you how to configure it in case you need it.

Once we have configured the plugin, we can execute it and see the status of our project. For that, open a console and launch this comand:

mvn dependency-check:check

Once we have configured the plugin, we can execute it and see the status of our project. For that, open a console and launch this comand:

This will instruct Maven to execute the plugin. It may take a couple of minutes if it is the first time you do it, but it also depends on how many dependencies you have in your project. Once it has finished, you should be able to see the results in the console:

But the plugin generates also a html report with more detailed information. This is normaly placed under /target/dependency-check-report.html and it looks like this:

As you can see, this project contains the famous Log4j vulnerability! So now we should figure out where it comes from. A nice way to start is checking our dependency tree:

mvn dependency:tree

Here are listed all the dependencies used in the project, so if we search for “log4j” we could easily find where this library is being imported from:

Eureka, now we know that this vulnerability is coming as part of spring-boot-starter-web:2.6.1, so what can we do now?

Establish a mitigation plan

It is almost an imposible mission to have 100% secure software on most of the projects, as new vulnerabilities are being found every day. Once said that, our best option to stay safe is to establish a mitigation plan, attending to the following questions:

  • How critical is the vulnerability? 
  • How does it affect to my project?
  • Is there sensitive information being compromised? (personal data, credit cards…)
  • How much time would the patch take? Does it worth it to be fixed?

This means, it is always good to keep the software with as low vulnerabilities as possible, but sometimes the risk is too low for the cost of fixing it, however, most of the times the way to go is just to update the dependency, as we may have an older version and the latest one may not contain that vulnerability anymore, so that is the first and to try.

In the case we are working on now, version 2.6.1 is currently the latest of spring-boot, so there is no chance to be updated yet. Best way to get rid of the vulnerability in this case is just exclude de log4j dependency from the tree, as this is just a demo project which does not need it, so that would fix it.

<dependency>
  <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
      <exclusion>
        <groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-to-slf4j</artifactId>
      </exclusion>
  </exclusions>
</dependency> 

A different option if you don’t want the dependency-check plugin to fail even if you have the vulnerability, is to use the before mentioned suppression file, which is just an xml file you can place in your project and add there all the vulnerabilities you want to exclude, or just the ones you are happy to live with. In this case it would be:

<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">

    <suppress until="2022-01-01Z">
        <notes><![CDATA[
        This suppresses the other Log4j vulnerability. JUST FOR DEMO PURPOSES!!
        ]]></notes>
        <cve>CVE-2021-44228</cve>
    </suppress>

</suppressions> 

Please keep special attention to this “<suppress until=”2022-01-01Z”>“. This is very important as the suppression file allows you to ignore that vulnerability until a defined date, so for example we could ignore the log4j vulnerability for 1 week so that the plugin remembers us that vulnerability again after that period, and there is hopefully a newer version of spring boot at that moment.

The power of automation

Now we know how to use the OWASP Dependency Check plugin, but we don’t want to keep launching the plugin the whole time from our localhost. 

One of the most efficient ways to take advantage of it is including it as part of our CI pipelines, so that Jenkins (or whatever tool you use) is incharged of checking the dependencies, making the pipeline to fail in case that some critical dependencies are found. 

If you use the common git flow approach, this will prevent to merge anything into master which contains vulnerabilities, and you will make sure that a feature branch won’t be merged until someone fixes the vulnerabilities. 

In my case I use Jenkins, and there is a plugin for it which is quite helpful as it reads the report generated by the pipeline and publish it to the pipeline, so we can check the results directly from there:

If we go inside the job that has failed, we could see what vulnerabilities have been found:

So yeah, now it is time to fix it, so once it’s done, next build should be green:

And that is all! I hope this helps you to analyze the vulnerabilities that your projects may contain, avoiding to bring any critical problem into production.

As always, you can find the project used for this post in my Github, so feel free to check it out ;).

Cheers!