Today there is likely no software project without some form of external libraries, dependencies, open source or whatever you want to call it. But how do you make sure you import healthy dependencies, which do not introduce vulnerabilities and risk into your software?
The explosion of open source
The amount of open source or other third party code used in a software project is often estimated as 60-90% of the total codebase. The total number of public repositories exceed 100M in 2018 according to GitHub.
According to our own findings, practically all companies developing software use open source, third party components or dependencies to varying degrees. Let’s call them dependencies from now. More often than not, hundreds of dependencies are used. This adds a new dimension to software development in that security issues in such code will affect the products in similar ways as issues in the in-house developed code.
As OWASP (Open Web Application Security Project) puts it:
“These component-heavy development patterns can lead to development teams not even understanding which components they use in their application or API, much less keeping them up to date.”
A similar explosion of vulnerabilities in dependencies
Meanwhile, as the use of dependencies increases, so does the number of flaws discovered. In 2018, there were about 16 000 new vulnerabilities discovered and assigned a CVE identifier.
That is more than 50 per day. This does not include other sources such as dedicated security advisories for certain projects and languages. The risk of using dependencies with known vulnerabilities has been included in the OWASP top 10 list of security risks. It has been given a prevalence score of 3 (on a 0-3 scale) and is thus regarded as very common and widespread.
As seen in the graph, it is also noteworthy how the rate of reported new and assigned vulnerabilities has increased by about 100% over the past few years.
These news are fantastic for attackers as they can spend less time finding complex exploits for single applications. Instead, they can exploit vulnerabilities for common dependencies that are used by thousands of developers and companies in their products and applications.
An infamous example is the Equifax breach, enabled by a vulnerability in the commonly used dependency Apache Struts. Struts is a web application framework for developing Java EE applications and in 2017 the CVE-2017-5638 was reported.
The vulnerability was fixed in a newer version of the software, but as discussed many companies do not keep track of their dependency versions and potential vulnerabilities.
After being known for two months the company Equifax (one of US largest credit reporting companies) had a breach which leaked, amongst other things, 200 000 credit card numbers.
The attackers used the CVE-2017-5638 vulnerability which meant that unvalidated input/unchecked data could be sent into the system. This is in essence a form of injection, one of the most common types of vulnerabilities Read more on the incident here (Equifax) and here (CVE).
With this in mind, it is very important for developers and companies to understand what packages are used and what risks they carry. Especially as we see consumers, investors and governments more aware of cybersecurity risks than ever.
In the light of GDPR and other similar international regulations it is increasingly difficult to hide attacks (which you of course should not). Additionally, customers can lose faith and abandon services if they feel their trust in the company has been violated.
The complexity of finding vulnerabilities
Nonetheless, checking what dependencies you use should not be much of an issue you think? That is a common view, which is slowly changing in the industry. The process of working with dependency vulnerability management (DVM, from here on after) consists of three steps.
1st – Data Collection
You want to collect as much information as possible from different sources about potential vulnerabilities. This includes, e.g., all vulnerabilities reported as CVEs. These are maintained by Mitre, an not-for-profit organization. NVD, the National Vulnerability Database, maintained by NIST (National Institute Of Standards and Technologies) adds severity scoring CVSS and CPEs, i.e., software version identifiers.
However, our research suggests that the information in these public sources is far from perfect. In fact, our findings suggest that nowhere near all of the vulnerabilities are classified properly, if at all. This means that you may get false positives or no results at all when browsing their data or using free tools which rely on this data without any cleaning.
Adding to the complexity, not all vulnerabilities reach the NVD database. Many stay within security advisories, mailing lists or even as mere issues in a GitHub repository. Even if they are not indexed by NVD, they are of course still available for exploitation.
2nd – Mapping the data with your dependencies
The second step is to use the information gathered about vulnerabilities and map it to dependencies you are using in your software projects. There is a wide range of languages, package managers and ways of specifying and importing dependencies.
Therefore, a tool supporting a wide range of languages is important.
But, of course, you want this to happen at developer level, when pushes and commits are made to be sure that no new vulnerabilities are discovered. And if they are, you want to know how they should be resolved.
This demands integrations to repositories and CI/CD (Continuous Integration and Continuous Deployment) such as GitHub paired with issue management boards, such as Jira. Vulnerability information then becomes a part of the usual developer team routine. We all know that developers do not want yet another tool to keep track of.
3rd – Visualization and remediation (fixing)
Hopefully, by now you have a list of vulnerabilities for your different projects. There are three primary actions possible for DVM.
- Do nothing, false positive, accepted risk
- Update the dependency to a secure version
- Do a workaround
In the first case, doing nothing,it is possible that you deem the vulnerability to be not critical enough to postpone the release of a new version of your software. It is a calculated risk, but the important part here is calculated and known risk.
In the second case, updating, it is a one minute job if a new version exists and does not violate any other dependencies or legacy code with new or changed functionality. This may require that several dependencies are updated at the same time. Such a procedure may at times become very complex.
The workaround can be used If there are no solutions nor updates available. Perhaps disabling a port in the firewall, or turning off a specific feature can stop an attacker from exploiting the vulnerability.
How can you go about setting this up?
Some have tried to do this manually, but the sheer amount of work and data is growing and is time consuming, difficult, and error prone to manage. It would require several full time employees and skilled security analysts to constantly monitor all sources to stay on top. If you do, however, want to give it a try, please head over to our Vulnerability Database!
This is why companies such as Debricked exist. We add automation to all steps in this process, providing timely and reliable information for our customers, integrating this into the existing development process. We constantly stay informed about the latest developments in security. Read more about how we do this by visiting our product page or contact sales.