In an Open Source World, How Do I Write Secure Applications?

November 30th, 2016   /   Posted by   /   Topics: Blog

open source

Open source applications have become pervasive. Even companies without an official policy end up with open source software in their code base, and more than half of companies contribute to the projects themselves. So how can you protect your application while leveraging technology from an ever-changing community of  strangers?

Let us first remind ourselves of The Parable of Left-Pad. In March 2016, a simple 12-line module called left-pad was removed from the Node Package Manager repository. What was its purpose? Removing white-space from the left side of a string. However, many popular and crucial packages relied on this tiny dependency: React, Babel, Gulp, and more. What you heard the day of its removal was the sound of a million builds breaking.

This may be a hyperbolic example, but it illustrates the fragility inherent in relying heavily on third party code. This was a bug in implementation, but if something like this results in a security flaw, then it could be hidden for a long time, just waiting to be exploited.

It Has to Be Said: Abstinence is Best

We get it: this is the real world and you are going to use a metric tonne of third-party dependencies and tools in your application. In fact, most modern applications are tiny little morsels of custom functionality stitched together with myriad third party libraries.

The verdict is still out on whether this is for better or worse, but we would be remiss if we didn’t approach this clinically and left it un-discussed: while it doesn’t protect against flaws in your own code, reducing the number of third-party dependencies also reduces the number of third-party vulnerabilities.

Let’s acknowledge the sacrifices — Not using third party libraries and tools means more proprietary code for you to write, more edge cases for you to fix, and building out more functionality that isn’t your organization’s core competency. Of course, all very valid arguments for third party code.

We believe that a developer who is properly trained in security-minded thinking can effectively replace certain third-party libraries with custom code without introducing their own security flaws. We also believe you can strike a balance between drastically reducing your time to feature-completion and mitigating risk. Here we suggest two things:

1. Look for Redundancies

Going back to the node.js ecosystem, a handy example of a redundancy in your third party code is the comparison of underscore and lodash. We have seen a lot of applications that include both even though they are nearly identical libraries. Be aware of this when you’re choosing to include third-party packages. Ask yourself: Do I already have this functionality in my app? Or something like it?

2. Prefer Larger Libraries, Healthy Communities

When the Left-Pad incident happened, the React community sprung to action and the library was updated, and back up and running in a day or two. However, due to the sheer number of libraries on NPM, there are likely dozens of libraries out there that still haven’t been patched.

Thus, it’s better to have fewer dependencies on larger libraries than many dependencies on smaller libraries. This way you have a better chance of risks being assessed, identified, and mitigated by the community at large.

If the library you’re using isn’t on a source-sharing community like GitHub, you can look at a few other things to vet: Are there any large organizations backing it? Is the documentation at least up to date? Can you find forums, stack overflow topics, social media posts about it? How many daily downloads does it have? How many unfixed bugs/issues? All valid questions and ways to see how active your tech’s open source community is.

Upgrade, but Upgrade with Care

Keeping your dependencies up to date is a FANTASTIC idea. Here’s are a couple things you can do to prevent yourself from shooting yourself in the foot too badly. Others have referred to this as “not getting cut on the bleeding edge.”

1. Understand Semantic Versioning

Most of the time, the version numbers in your packages mean something. One of the most common versioning schemes is something called Semantic Versioning. It means that given a library with the example version number 1.4.1:

  1. A MAJOR upgrade to version 2.0.0 would introduce API-breaking changes, almost certainly requiring a rewrite of the code that implements the library.
  2. A MINOR upgrade to version 1.5.0 introduces new functionality, but in a backwards compatible way. More often than not this is good news, and will not require a rewrite.
  3. A PATCH upgrade to version 1.4.2 introduces bug fixes and security flaw patches. These are always good news, and what you are looking for when upgrading for security reasons.

Note that many popular open source libraries will keep doing security and bug fixes on older major versions because people can be reticent to upgrade – so there might be a 2.4.1 release as well as a 1.4.2 release.

2. Understand how your lock files work

In most modern package management systems, you can maintain fine-grained control of the versioning of your dependencies using what’s typically called a lock file. The implementations are slightly different but the concept is fairly universal: you have a file which is checked into your source repository that functions as a manifest of the dependencies you have, and your desired versions.

In PHP, you would use composer, whereas in node you would use either package.json or the newer Yarn technology. In Java you have maven or gradle, and in ruby you have bundle. All different shades of the same idea.

Use Vulnerability Databases

Lucky for you, some organizations have made it their entire business to keep track of vulnerabilities in open source and other third party libraries. Here’s a list you’ll find helpful:

  1. OWASP Dependency Check is primarily for .NET and Java but they are adding experimental support for other languages like Ruby and Python.
  2. The National Vulnerability Database is sponsored by the US Government. It is technology agnostic, and ugly but it has a great compendium of known vulnerabilities across thousands of products and packages. For example, here’s OpenSSL
  3. If you’re on the node.js platform, Snyk is a great tool for this. It can examine the nested dependency chain in your node_modules folder and provide feedback on known vulnerabilities and also alert you when they discover new ones.

Build Security Tooling Into Your Build Step

Once you’ve learned how to use tooling to find vulnerabilities into your app, take it one step further – automate it! A lot of these tools provide functionality that allows you to check for vulnerabilities during your build and deployment steps, making it just as easy to run a security test as it is to run a unit or functional test.

Going back to the Snyk example, not only do they integrate into your CI flow, but they will actually create automated pull requests on GitHub to fix your vulnerable dependencies. Very cool.

Your continuous integration is another good place to practice “continuous security.” If you’ve written proper abuse cases based on an adequate threat model, then you might even be able to detect third-party vulnerabilities on your own!

You Can Become an Open Source Security SME

Third party tools aside — now, more than any time before, the onus is on developers to own the security of all of their their application code, dependencies and custom code. Think about it: nobody knows the tech better, and thus nobody can protect it better.

This is a call to action: become security subject matter experts of whatever languages, database engines, and frameworks you work with. Of course, do the things in this article: use vulnerability databases and tools to examine your third party code, but also join the conversation on GitHub, at conferences, and at working groups.

We know you have to use third-party libraries, but we also want you to be safe.

Developer Tools for Security

The Codiscope content team writes tutorials sourced from our technical staff and commentary based on trending topics in software development. We usually choose topics that we think will be interesting and informative, but we're open to suggestions. Tweet us with your topic ideas!

Read more by Codiscope