Secure Your Application From Vulnerabilities in Open Source Libraries

Amey Anekar
9 min readDec 29, 2020

--

TL;DR

  1. Open Source Libraries are great, they are free. But, they can be a nightmare if vulnerabilities in them are not managed effectively.
  2. You accrue Security Debt by installing seemingly free open source libraries.
  3. Least you can do to manage this risk better is using a solution that scans your codebase periodically for vulnerable libraries.

Can you imagine writing a decent-sized application using only native libraries provided by your language? No external dependencies. Do you think you would be able to pull off such a stunt? How confident would you be regarding the resiliency of your code where you had to mimic a library from the ground up, knowing very well that there was an open source alternative available for it?

I would certainly not be very confident writing my code from the ground up, without using external dependencies. How can I be sure that I have covered all the use cases and edge cases in my code. I would be better off relying on open source libraries that are generally trusted by the developer community for their critical software projects.

Open Source Libraries To The Rescue

Open Source Libraries are great. There are ton of them. Almost any problem that you come across while coding, there is another developer whispering in your ear saying: “There’s a library for that”.

We have become so reliant on open source libraries that it feels almost criminal to write code from scratch.

You often hear phrases like “Don’t reinvent the wheel”, “Don’t Repeat Yourself” or “Keep It Simple Stupid”, when it comes to writing clean code. In this obsession to write clean code, we end up importing code written by unknown individuals, no matter how badly that has been written, because we are hardly ever going to need to look at their code, as long as they provide simple to use APIs.

Open Source = Innovation

Organizations also heavily rely on open source libraries to speed up their development lifecycle and release the next cool feature to the market. If companies had to be bogged down by the need to build software from ground up without relying on open source libraries, we would not be seeing the pace of innovation that we are experiencing today.

Open Source Libraries Seem Free, But They Are Not

When you get something without a monetary or time investment, you consider that thing as free. But, what seems to be free today, may come back to haunt you in the form of Debt tomorrow. You have heard the concept of Technical Debt, I am sure. Well, Security Debt is the new Technical Debt.

Adding open source libraries to your project is like taking on security debt which you do not even know you would be liable to pay at a future time. Open source libraries contain code that you did not write, but you need to manage nonetheless. It is difficult to manage code that you have not written, especially if the code is badly written. Who takes time to analyze the code in open source libraries as long as they are providing clear and concise APIs and documentation.

What happens if the maintainer stops maintaining the library, but you have added this library as a dependency in almost every application within your organization. Now imagine what would happen if a vulnerability were to creep up in this library.

Who is responsible for patching this security vulnerability? The maintainer? No, you are. The owner/maintainer of the library was doing their job voluntarily.

What About Dependencies of Dependencies of Dependencies of …

More often than not, the libraries you use in your projects in turn depend on other libraries internally, because they are developers like you and me. They too do not want to reinvent the wheel and would like to leverage on libraries written by someone else.

So, you not only need to worry about vulnerabilities in the dependencies you directly include in your applications, but you also need to worry about transitive dependencies that are included by these direct dependencies.

Usually, library authors require a specific version of their dependencies to avoid breaking their own code when there is an update in the an underlying dependency. So, even if an underlying dependency has been updated because of a security vulnerability, you cannot update it because your direct dependency wants the older version for it to work correctly and updating it may break some of your core functionality.

Breaching Your Trust Boundary

When you consciously write secure code to safeguard your application and data from attacks originating from the Internet, you are actually building a trust boundary. A boundary between what is Untrusted and Bad — The Internet and what is Trusted and Good — Your Application.

You may unknowingly introduce security vulnerabilities that may allow perpetrators to breach this trust boundary and get a foothold into your application when you import a library with known vulnerabilities. You are importing code written by some random individuals on the Internet to your application. Are they following the same secure coding practices that you follow in your application?

Importing an open source dependency to do one small task in your app expands the attack surface of your app if the library you are importing has many more functionalities which you do not even need.

Bear in mind that when you import an open source library into your project, you own the risk of security vulnerabilities that the library may contain. This is an unknown. You do not know if the library you are using contains security vulnerabilities or what type of vulnerabilities these might be.

What Should You Do to Manage Vulnerabilities in Open Source

Well, all this sounds too scary. I cannot merely present a problem to you without letting you know how to start managing this risk better.

There is a lot you can do to manage vulnerabilities emanating from your open source dependencies.

If you are paranoid about vulnerabilities in your libraries, the most extreme step you can take is to own the code contained in these libraries and run security tests on them such as SAST, DAST, manual code review, etc. Obviously, this may not be practical in every situation. Especially, when your project contains hundred of imported libraries, including both direct and transitive.

The least you can do is: Update Those Dependencies

Updating all dependencies in your project would take care of security vulnerabilities that have been patched through a version upgrade by the maintainer.

But what above vulnerabilities that yet to be discovered? How often will you update your dependencies? How frequently are you going to monitor your dependencies for security vulnerabilities? Tracking all this and managing the update cycle is a mammoth task in itself.

As developers, we want to be focused on writing good code that brings new functionalities to our applications which our users can enjoy. We don’t want to keep ourselves worried about the these petty processes.

Even if you have an independent DevOps teams to manage this for you, things sometimes get lost in communication and vulnerabilities may creep up in production even when they had been identified and notified by the DevOps team.

The easiest thing you can do as of now is to integrate a solution that continuously monitors your dependencies for published vulnerabilities. New vulnerabilities are going to be discovered in open source libraries, there is nothing you can do about it.

There’s an App For That

I tried researching solutions available for monitoring software dependencies for published security vulnerabilities.

That’s when I came across Bolt from WhiteSource as a noteworthy contender in this space. The feature that immediately got me hooked onto Bolt as my go-to solution for scanning vulnerabilities is its integration with Github and Azure DevOps.

All my code is on Github, mostly in private repos. But this integration gave me the ability to quickly try out what Bolt had to offer. So, I installed its GitHub App. To try it out, I knew the exact candidate. I had a React website in my repository, which I had purchased from one of those template websites. I had a feeling that this would be riddled with vulnerabilities.

So, I set this app to scan only this React repository. Let me take you through the process of setting up Bolt on your GitHub account.

How To Setup Bolt for Your GitHub Repository

#1 Install WhiteSource Bolt to Your GitHub Account

Visit the WhiteSource Bolt page on the GitHub marketplace and initiate the installation from there.

#2 Setup Repository Access

During the installation flow, GitHub will ask you whether you want to give Bolt access to all repositories or only to a select few. I selected only one repository as I was trying it out. You can later modify this permission from app settings page.

#3 Merge The Pull Request

As soon as the setup is complete, you should see a pull request from the ‘whitesource-bolt-for-github’ bot in your repository. This pull request adds a file named .whitesource to your repo root. This file contains the configuration settings for Bolt.

To start with, the default configuration should work fine, so don’t bother changing these settings at this point and just merge the Pull Request

#4 Wait anxiously for the alerts to flow in

10 minutes after I merged the pull request, I started receiving email alerts from Github for new issues being created on the repository. Bolt create a unique issue for every outdated library it finds in your repository.

Bolt identified 36 outdated libraries in my repository within a few minutes.

#5 Understanding the Issue

Here’s what a typical issue created by Bolt looks like:

#5.1 Vulnerable Library

The details suggests that this vulnerable library is a transitive library that is embedded five levels deep in my dependency hierarchy. That’s amazing.

#5.2 Vulnerability Details

This section explains the vulnerability in a simple language, that would allow you to prioritize the fix. From the description above, it seems to be a Regex Denial of Service vulnerability (ReDOS).

#5.3 CVSS 3 Score Details

This section provides information about the CVSS base score metrics. If you understand CVSS metrics well, this section can be very helpful and allow you to further prioritize your fix.

#5.4 Suggested Fix

Bolt also provides the fix available for this vulnerability. It seems that this vulnerability can be mitigated with a minor upgrade to v0.1.4. This is helpful information right there in the Issues tab. You don’t need to go hunting for remediation information elsewhere.

How Often Does Bolt Scan your repository

Bolt scans your repository every time you make a push to the repository with changes to your package manager configuration file, that is, whenever you make changes to your imported libraries. Bolt provides a list of valid package manager configuration files.

In the Free Version, these scans are limited to five times a day. Bolt also provides a paid Full Solution which does not enforce this limit, plus has a ton of other features that makes the lives of developers and DevOps teams easier.

Bolt support 200+ languages, frameworks, and development environments. That’s a lot. I know five languages at the most and can name no more than 20 languages.

Integrates with GitHub Branch Protection Rules

Bolt can block merging of pull requests, if it finds that the pull request is trying to integrate a library that has a known vulnerability. That’s a good way to preemptively block vulnerabilities from entering your codebase. Details about how this can be done can be found here.

That’s All

I hope you enjoyed reading this not-so-short account of how vulnerabilities could creep up in your codebase through vulnerable open source libraries. Now, you go ahead and setup Bolt for your GitHub or Azure account, while I go and fix my vulnerable packages.

--

--

Amey Anekar
Amey Anekar

Written by Amey Anekar

Security Analyst aka Triager @HackerOne. Curious. Minimalist.

No responses yet