In March 2017, over 140 million people’s sensitive information was stolen from Equifax company servers. How did it happen?
Equifax was using the Apache Struts framework to run a number of its websites. In March 2017 a security vulnerability (CVE-2017-5638) was discovered in Apache Struts and on March 7 Apache has released a security patch fixing the aforementioned vulnerability.
On March 9 Equifax administrators were instructed to apply the patch to any affected software. But they did not do it. On March 12 attackers gained access to Equifax’s internal servers which resulted in one of the biggest data breaches in history.
In this article, I will dive deeper into the security scanning process which I described shortly in the article How To Keep Code Quality Under Control In 7 Steps. However, this time it won’t be about security scanning of our code but dependency scanning.
Table of Contents
What’s Wrong With 3rd Party Dependencies
Let’s take a high-level view on the usage of 3rd party components in the software industry. Below are key findings from an audit conducted by Black Duck on over 1000 commercial codebases:
- 96% of all scanned applications contain open source components,
- use of open-source code increased from 36% to 57% over a one year (end of 2017),
- the average number of open-source components per application is 257.
Furthermore, according to Veracode:
- applications are composed of up to 90% open-source code,
- developers downloaded more than 52 billion Java components (and 12 billion Docker Hub components) in 2017,
- the use of open-source software increased by a factor of 5x over the past 5 years.
It becomes crystal clear that software nowadays is mostly built of open-source dependencies and the number of 3rd party dependencies will only grow in the future.
Applications security risks
Unfortunately, with a growing number of 3rd party dependencies, the risk of introducing security vulnerabilities into our software grows.
Components, such as libraries, frameworks, and other software modules, run with the same privileges as the application. If a vulnerable component is exploited, it could facilitate serious data loss or server takeover. Applications and APIs using components with known vulnerabilities may undermine application defenses and enable various attacks and impacts.OWASP Top 10: A9:2017-Using Components with Known Vulnerabilities
To clarify, it doesn’t mean that open-source software is anyhow riskier than proprietary components and we should avoid using it. You can find opinions about the security of open-source components from some top open-source developers here.
So, how big is that risk? Well, according to Veracode’s State Of Software Security report, the risk is quite high:
Nearly 88% of Java applications have at least one vulnerability in a component.Veracode. State of Software Security, Volume 9.
Before we discuss tackling this problem, let’s check how many dependencies you need to run a simple Spring Boot application.
Sample Spring Boot App Dependencies
I used Spring initializr to generate a sample Spring Boot project with some popular dependencies as depicted below:
Below you can find a list of all dependencies for the sample app:
So, for the sample Spring Boot application, you will need additional 55 JARs (37 MB) to make the app start and run successfully. Furthermore, the number of JARs depends on the additional features/tools that we want to use and it might get much bigger.
For example, in one of the projects I am working on currently, there are 262 dependencies.
However, the big number of 3rd party dependencies makes the whole security checking process quite difficult. Why? Let’s see how you could check (manually) if your dependencies are free from known security vulnerabilities.
3rd Party Dependency Scanning Process
Below are the steps of the manual dependencies checking process:
- Firstly, gather given dependency identifying information (e.g. Vendor, Product, and Version) to build Common Platform Enumeration (CPE). For example, CPE for
- Secondly, search through the Common Vulnerability and Exposures (CVE) database like NVD using the identifier from the previous step and check if there are any volnerabilities for the given dependency
- Repeat the first two steps 55 times (in our exemplary case)
So, doesn’t look that bad, right? Well, let’s ignore for a moment the fact that dependency scanning in the way shown above takes some time and you need to do it manually.
The real problem is that new vulnerabilities can show up in the CVE database at any time.
You can’t assume your dependencies will be secure forever just because you checked them in the past. And that means that you have to check your dependencies in the development/testing phases and when the software is running in production.
Automatic Dependency Scanning
So, we know that dependencies checking is something we have to do regularly. Moreover, we need to check the dependencies of the software that we have already released, so that we could prepare a patched version before our clients come to us with security vulnerabilities they found in our software.
Believe me, this is not something unusual. Companies around the world are paying more and more attention to software security.
Let’s see then if any tools can help us to keep our dependencies free from vulnerabilities.
Below you can find the two most popular tools in the Java world that allow us to check dependencies against vulnerabilities databases quickly and easily:
- OWASP Dependency-Check – a simple tool that scans Java and .Net application to identify the use of known vulnerable dependencies. You can use OWASP DC as a standalone command-line tool. In addition, you can integrate it with your favorite build tool (Maven/Gradle) or use it as a step in the CI/CD pipeline (e.g. Jenkins).
- Snyk Open Source – this tool is much more advanced than OWASP DC (however, it’s free only for a limited number of scans monthly). It doesn’t only scan app dependencies and show potential problems. This tool can prioritize issues that are most worthwhile to fix and suggest automatic updates, check if the vulnerable function is reachable by the app’s code, and check whether vulnerabilities are called in the runtime.
In short, these tools can help us with listing 3rd party dependencies in our apps and indicating the ones with known vulnerabilities. Additionally, they give us information about the severity of its findings.
However, not every security vulnerability is a risk for our application. For example, we might not be using the affected feature in our code at all. This of course requires deeper analysis than just a simple dependencies vulnerabilities scan.
To sum up, 3rd party dependency scanning is one of the pillars of the Shift Left Security approach. In other words, it means that we should integrate security scanning early in the development lifecycle.
To do this, we need:
- Tool – which we can use to scan our application’s dependencies e.g. OWASP DC.
- Automatic scans (regular and frequent e.g. triggered by commit to repo) – we can achieve that by integrating scanning tool with our CI server e.g. Jenkins OWASP DC plugin or our build tool e.g. Gradle OWASP DC plugin.
- Vulnerabilities review and remediation process – once we have found a vulnerability we should take a closer look at it and decide whether to ignore it or upgrade the dependency to the closest secure version.
The last point I mentioned above might be the most problematic one.
Firstly, we should involve the InfoSec team in reviewing the findings of our dependency scanning tool. Depending on the severity and actual impact on our application, we might not need to do anything with it and simply ignore it. But remember that this has to be a carefully made decision.
Secondly, once we have decided that we need to patch the vulnerability, we should be ready to deliver the patched version of our application fast. Especially, when that version is already in production.
In the next article, I will show in detail how to use the OWASP DC tool and how to integrate it with a build tool and CI pipeline.
Thanks for reading and stay tuned!