Imagine that you’ve been working on a node.js project for a few years now. You started or joined it when you were younger. The code works, you can vouch for that it’s good and secure for yourself and your team. But how do you validate all those NPM modules that saved you so much time and effort over the years? It works, nobody has hacked you yet, so why should you bother?
The costs of a data breach can cripple a well-established company, not to mention potentially being a death sentence for a startup. And that is without mentioning the governmental regulation introduced with EU’s GDPR act and GDPR inspired laws across the globe. This is why it’s very important to take efforts on every level to reduce and mitigate the security threats of the software you develop.
Tools for checking packages
Let’s start with some simple commands you can just add to your build script or as a CI/CD step.
The dedupe command simply tries to simplify your dependencies by moving them up the tree. In essence, trying to have a single compatible dependency that can be used by more packages, instead of each having its own slightly different version. Fewer versions to deal with simply give fewer attack vectors through said dependency (newer versions tend to have fixes for already known and published vulnerabilities).
OWASP dependency check checks the dependencies against a publicly known database of known vulnerabilities. It has a CLI tool which locally stores the whole database against which it checks. This makes it appropriate for systems in which you don’t want to give full access to.
This command-line utility allows you to both check for bad dependencies and will prompt you to confirm if it notices that you are trying to install a package with known vulnerabilities.
Going beyond automated checks
Besides things you can add to your general code workflow, you might periodically want to go deeper into the analysis of packages. Try answering the following questions for your project:
What am I using this module for? Is it still necessary?
- Are there any cases of different modules (or our code) being used to solve the same problem?
- Which packages bring in most submodules? Can I replace them with some “flatter” packages?
- Are they all still in active development? Which ones haven’t been updated for a long time or don’t have any active developers?
- Take a look at their issues/bug tracker, are there any reports of vulnerabilities or bad code?
- Are they publishing test coverage, passing and/or any other code quality metrics?
The questions above will help you evaluate if any of the packages have to be updated or replaced with alternatives or even coded by your team. But you might have to go even further. The questions above focus on a few attack vectors; mainly cases where developers intentionally or by mistake have introduced vulnerabilities into their codebase. But what about if the user account of the publisher gets compromised?
Bad and duplicated passwords are a reality that impacts the security of every online service, npm registry included. If you have a publisher’s password you could git clone his code, add your malicious code, build and publish it to the NPM registry. Everything would look fine, and it could be months and millions of downloads before someone notices that there’s anything wrong.
So, what to do?
There are a few ways you could go about validating for the above:
- Compare git commit hashes between GitHub and the version you download from the registry.
- Downloading the source and building it yourself, and then comparing it to the downloaded package from NPM. Running tests and benchmarks against both versions and looking for any change in results and performance could reveal a code discrepancy that may indicate a potential for malicious code.
Look for a new possible attack vector
This post started with some simple steps you can take to increase security. Everything beyond tends to get more complicated, and is hard to do on a day to day basis on a project. Besides knowing what vectors can be used to compromise your application right now, you also have to be mindful of potential future attack vectors (that are still unknown or never attempted against npm registry/packages). And, sadly, for this, there is very little you can do besides reading blogs, attending conferences, looking for official announcements or having a dedicated security specialist do it for you.
But with a cloud-based vulnerability scanner, you are not only subscribing to the current state of the art vulnerability checking. You are also delegating all the expertise and research that you or your team would have to acquire and constantly stay updated on in order to have an in house solution for security validation.
Previously published at https://debricked.com/blog/2020/03/11/how-to-evaluate-the-security-of-your-npm-package-dependencies/