Dependencies: It’s Not Just Your Code You Need to Secure
Developers must not only check our code for vulnerabilities but also our dependencies to make our applications more secure.
Join the DZone community and get the full member experience.Join For Free
Original article published by Cristián Rojas at Hackmetrix Blog
The EQUIFAX USA data breach of 2017 put a spotlight on an under-considered aspect of software security: it’s not just our code that we need to secure. The Equifax problem was about a massive web portal hack that compromised the data of hundreds of millions of people. Securing the code here wasn’t enough.
The facts of the case are widely known, but its cause? Not so much. Little is said about the fact that this leak would not have taken place if the developers of the EQUIFAX application had upgraded their Apache Struts web framework to a more secure version.
Ensuring software dependencies were in place would have helped considerably. We have already discussed how hidden dependencies can create bottlenecks that will impact an entire system.
Web developers are not creating applications based only on our code. We rely on servers, programming languages, frameworks, and libraries (wheels, gems, JARs…), and we need to secure all of that, even code that we copy-paste from Stack Overflow.
When we create applications, we are not just writing code; we are building a house with Lego blocks, and our code is just a part of that house. In fact, our code is on the top of that house. All that other stuff we depend on is underneath, it’s our software’s foundations, and if it is not secured, our house will fall apart, just like EQUIFAX’s did.
One notable thing to mention in this issue is the fact that this kind of vulnerability is listed in OWASP Top 10 2017.
The good news is that some developers have begun to take notice of these issues. There are projects available that aim to help developers take care of dependency security even before their code reaches the CI/CD (Continuous Integration/Continuous Delivery) server.
These tools are continuously updated, based on security data obtained from CVE (Common Vulnerabilities and Exposures) data and developer reports, and can be used in CI/CD servers as well.
Learn about them here.
What Happened With Equifax?
Equifax was a major data breach where a complaint portal was hacked, exposing a vulnerability that a software dependency may have been able to patch. The hackers migrated from the portal to a separate server where they were able to more freely access consumer usernames and login credentials.
The data was taken from a network through encryption methods that were, at the time, undetected and had been for months. It was a slow leak of sorts. The IT gods at Equifax didn’t see it coming, and many say they should have. Software dependencies may have been able to prevent this from happening.
What Are Software Dependencies?
Software dependencies are reused coding libraries or packages in new software. It is the reliance on old libraries for development instead of starting your code from scratch.
Dependency is a coding term that refers to how one segment of software relies on another in order to function. Software set A needs Software set B in order to function. So you can develop a web page, for example, but you still need a software program to see it.
The most common examples of programming dependencies are libraries, online services, and running multiple scripts simultaneously.
There are some dangers of using dependencies with your code, and some will say that it is typically frowned on. That is because when you have one program depending on another, a breach to one is a breach to all.
You can not always control outcomes here, which is where your risk is going to increase. However, strength in one set is strength for all.
It is more important than ever to develop custom libraries accordingly. With applications like Apple’s Swift and others like it becoming increasingly more versatile every day, dependencies are critical.
Every application requires its own set of coding, and software dependencies are critical. With more and more focus on custom library development, breaches like the Equifax breach simply would not happen.
Languages like Swift and Python have become popular for this reason. For Java-based projects, using Maven as your automation tool can help. Use these tips to improve Maven efficiency with your Java script.
The software and its security can be coded in just a few weeks, and successfully. And when it is not, the security positioning is incredible. If a tested library is already in place and secure, why reinvent the wheel? Lean on those dependencies.
There are a few examples that you can draw on.
OWASP Dependency-Check (Java, Multi-Language)
The OWASP, the Open Web Application Security Project offers a number of free tools and resources that can help you to improve your software security.
The main reference when it comes to dependency security checking is OWASP’s dependency checking tool, which is mainly thought for Java projects but has been expanded to other platforms, like .NET, with experimental support for Ruby, Node.js, Python, and C/C++.
Java is always going to be a crowd favorite, and there are ways to improve Java efficiency, like Unit testing. We don’t need to tell you that creativity comes in handy.
Bundler Audit (Ruby)
Bundler audit is a tool that helps you to locate security vulnerabilities and provides patch verification. Bundler Audit is made with the popular language Ruby in mind. Its vulnerability database is GitHub repository-based, and it is regularly updated. This allows Ruby developers to keep their gems up-to-date in security terms.
Package Manager Support
The even better news is that package managers have begun to take notice, and they take security a step further by integrating dependency checks into their features. There are notable cases.
Pipenv is Python’s magical packaging tool that allows developers to resolve common issues, and make development a more concise process. Pipenv is a packaging tool for Python that is gaining momentum every day and brings together many aspects of Python development: management of virtual environments (virtualenv), package definition (pip), and others.
One of its included features is a package security audit, right out of the box. If you still use pip, no problem. Just install the safety package, and you will get the same protection.
Since version 6, the Node Package Manager includes an audit feature that allows developers to check for vulnerabilities in their projects’ dependencies.
One notable thing about this functionality is that it also warns about potentially functionality-breaking upgrades based on the Semantic Versioning standard.
Continuous Integration? Yes, But…
Some of these tools already have CI/CD system plugins available for servers like Jenkins, and they work quite well. In the case of the tools that don’t, integration to these systems is not that hard.
Now, we shouldn’t wait until our code reaches our repositories (and our CI servers) to see if our dependencies are secure. Dependency security checks should be done by every developer before pushing their changes to the repository. Don’t get busted by the CI/CD server.
How to Fix Security Vulnerabilities
Fixing the issues reported by these tools may seem easy: just change the library version, and that’s it. But you need to test the changes locally before pushing your code.
Many packaging systems are automatic when syncing versions and dependencies of your dependencies are upgraded easily. But this may cause functionality breakage. This is the main reason the community created the Semantic Versioning standard.
Usually, security vulnerability mitigations are put in the patch versions, but sometimes, you will need to upgrade to a minor or major version, and if that happens, you must do feature testing, because these kinds of upgrades could cause problems with functionality.
Not Just Libraries for Resolving Security Issues
The tools we saw earlier allow us to check vulnerabilities in libraries/frameworks. But we don’t just depend on those. Servers and our (every day more) virtualized infrastructure should be checked for security vulnerabilities. Automatically.
Tools like Ansible, InSpec, or OpenSCAP can be leveraged to alert of any security problems that our servers may have integrated to CI/CD pipelines.
Secure Software Dependencies
Dependency management is important, and there are plenty of DevOps tools to help you. Developers must check not only our code for vulnerabilities but also our dependencies to make our applications more secure.
This process should be automated, but not dependent on automation: we need to be more proactive and run our available tools before committing changes. This way, we will be one step ahead of malicious actors who intend to harm our software and its users.
Published at DZone with permission of Nando Delgado. See the original article here.
Opinions expressed by DZone contributors are their own.