Automated vulnerability checks and the end of NSP

by Rouan Wilsenach

Exploiting known vulnerabilities is still the number one way attackers compromise a system and is on the OWASP list of the Top 10 Most Critical Web Application Security Risks, so we’ve made automated vulnerability checking an important part of our development flow here at Tes. We’ve been using nsp, a neat little command line tool from the Node Security Platform (NSP), to find known vulnerabilities.

All good things come to an end

The NSP was recently acquired by npm and has just been shut down. The NSP advisory database is now available on npm’s site and npm have introduced an npm audit command in npm version 6, which helps you run a programmatic security audit in the same way the nsp command line tool did.

NSP Alternatives

There are a few different options for replacing nsp, including Snyk, retire.js and GitHub’s security alerts.

While having a number of these options available is useful in order to satisfy each of our services’ unique needs, I think npm audit is a sensible default option. First of all, it’s free and built into npm, a tool we already use everywhere. It’s also something you can run programmatically, which I find essential in order to build it into our software development workflow. In addition, with the new “Report a vulnerability” button on their package pages, my guess is that npm will become more likely to know about a vulnerability first.

That said, it really doesn’t matter which tool we use to audit our code for vulnerable dependencies. The important thing is whittling our list of known vulnerabilities down to zero.

Why zero?

When looking at a list of a hundred known security vulnerabilities in a project, one may wonder why it’s important to go through the (very hard) work of getting it down to zero. It would be much easier to go through the list to find the vulnerabilities that most affect you and skip the rest. Here’s why I think getting to zero vulnerabilities is worth the effort:

Attackers are much better at exploiting vulnerabilities than you are. You are likely to overlook potential attack vectors, especially considering that attackers often exploit combinations of known vulnerabilities in order to compromise a system.

How will you spot new issues? Let’s say you manage to deal with all of your “actual” security vulnerabilities and get your list down to N vulnerabilities. Will you notice when your list goes from N to N + 1? I say that, unless N = 0, you won’t.

Reassurance as a feature. We have a great open source and inner source culture at Tes, so we’re often writing code other people will use. As our industry is becoming more security aware, consumers of libraries (rightfully) expect to be put at ease that software maintainers are taking steps to avoid security issues. If a consumer finds an audit warning on installing your library (npm install now reports these by default), they will move on and use something else even if your library isn’t directly affected by a vulnerability. It’s our role as maintainers to keep a clean slate and reassure our consumers that we’re paying attention.

When to check

On every push

We’ve built npm audit into the pre-push git hook of many of our repositories, so that we can find new vulnerabilities before they even reach our version control services. These pre-push hooks fail when npm audit reports any vulnerabilities. I’ve found this approach exceptionally useful, because you become aware straight away of issues in services you’re actively developing. On a few occasions, we’ve even been able to be part of the effort to address a vulnerability by helping patch open source libraries we depend on.

Regularly

Unfortunately, the pre-push strategy doesn’t help at all when your service is not under active development. A well-designed microservice can easily be working away without fuss for months without anyone needing to change it. How do we detect whether it’s using known vulnerabilities when nobody is pushing new code? For this, you can rely on your CI tool to regularly run a build that checks your repositories for known vulnerabilities. GitHub’s security alerts are also a great option for this, but you’ll need to remember to opt in for your private repositories.

Working through the deluge

If you’re building automated vulnerability checking into your repository for the first time, you’re likely going to be surprised by the number of vulnerabilities these tools will find. Basically, all those major version bumps you’ve been putting off are suddenly going to become very important. This even happened when we switched from nsp to npm audit, which found many more vulnerabilities than its predecessor.

Staring at an npm audit report with 50+ vulnerabilities can be extremely overwhelming and disheartening, so I wrote npm-audit-helper as a tool to help address this problem. It helps you focus on the highest severity vulnerabilities first and points out dependencies that are responsible for the greatest number of vulnerabilities. It also gives you options for controlling its exit code so that you can build vulnerability checking into your workflow even before you’ve managed to get down to zero vulnerabilities.

There are also options built into npm and some other libraries that you may find useful – take a look at the short list of npm audit hints I’m curating.

One step at a time

With so many recent security and data breaches, it’s really great to see the software engineering community step up to start putting security front-of-mind. Npm have appointed Adam Baldwin from the Node Security Platform as their Head of Security and are actively building new security features. Over time, I can see this leading to an increased awareness of security issues in our industry, but for now you can build automated checks into your workflow and start working towards getting your own repositories vulnerability-free.