Triaging Known Vulnerabilities in Your Dependency Tree with NCM Desktop
With our October 2018 Update, we’ve introduced a suite of enhancements to NCM Desktop in Beta 3.
One of the features that I’m personally excited about is a small but useful one – we’ve introduced Dependency Chains inside NCM Desktop:
Dependency chains have been a feature of N|Solid since 3.0, and are a vital part of the vulnerability triage story. With this release, dependency chains are now an integral part of the NCM issue triage story as well.
In this guide I’ll be using two things:
- Required: NCM Desktop with my NodeSource Account
- Optional: Goof from Snyk as an example insecure application to triage security issues – feel free to use it as well, or follow along using your own application!
Module List Dependency Chains
Previously, NCM Desktop surfaced security and compliance issues in the dependencies your applications included… but you weren’t easily able to tell if those dependencies were a top-level dependency or nested somewhere within the tree.
With the introduction of dependency chains, you now have this differentiation at a glance in the module list:
You’ll notice that all modules have a tree icon in front of them except for adm-zip@0.4.7
and st@0.2.4
. Each module with a tree icon is a nested dependency that was introduced by a top-level module, somewhere in their tree.
Because both adm-zip@0.4.7
and st@0.2.4
lack the tree icon, we can easily tell that they’re introduced at the top level of our application. This will ideally help you quickly identify which modules can be quickly resolved and which ones may take a bit more work.
Beyond just serving as an indicator of whether or not a module is deeply nested, you can actually dig in a bit further and see the entire dependency tree that led to that module being included. For example, if I hover over the tree icon I can see that negotiator@0.2.8
was introduced by st@0.2.4
:
Since there are two direct issues being introduced by st@0.2.4
, we’ll try resolving some of them by updating that module!
Resolving an Insecure Top-Level Dependency
Let’s start by opening up the st@0.2.4
module view to get an overview of what we’re dealing with:
It turns out st@0.2.4
is actually introducing two medium vulnerabilities by itself, not counting its dependency tree.
You’ll notice that there’s a "Patch available" section beneath each of those vulnerabilities. The version that is mentioned in both – st@1.2.2
– is the version that has the specific vulnerabilities resolved. In this case, it’s easy since st@1.2.2
is the patched version for both.
After updating the project’s package.json
, ensuring our code is compatible with the updated module (and making any needed changes), and npm install
ing, we should be rid of a few vulnerabilities.
One nifty enhancement from the last beta is that NCM Desktop will now automatically detect any changes to your applications’ dependencies in the background, so if you switch back to NCM Desktop now you’ll notice that we’ve got 2 less total vulnerabilities, as noted in the top right corner of the project:
If we want to dig in a bit more to what actually changed when we upgraded to st@1.2.2
, we can look at the "Added" and “Removed” filters, we’ll see exactly what changed.
Here’s the "Added" filter – looks like everything is 100% okay:
Here’s the "Removed" filter – looks like we got rid of those two vulnerable modules and a few totally okay ones. No sweat:
The "Added" and “Removed” filters are extremely handy for understanding your applications’ health and security as you’re working on them, showing you a play-by-play of what’s being added and removed as it evolves in real time.
We’ve just improved the overall reliability and safety of our application with a relatively simple change in our dependencies. Yay for simple and impactful changes!
Resolving a Nested Insecure Dependency
We’ve already resolved an insecure top-level dependency, and coincidentally resolved a nested dependency. What about nested dependencies whose top-level module is itself secure?
In this case, we’re going to pick on fresh@0.2.4
which is introduced into the dependency tree twice by express@4.12.4
. Digging into the module detail view, it has a high severity vulnerability:
We can see that express@4.12.4
is the module introducing it here. If we go back to the module list, search for express, and open up the module we can see that this version was released two years ago:
I personally know that Express has been actively maintained and developed over the past two years, and that there are definitely more modern releases that have shipped since then – I’m not at all surprised that a two year old version introduces vulnerabilities.
To investigate, we could just npm install express@latest
and see if that resolves the issue… but that defeats some of the fun. Let’s open up the repo by using npm repo express
, and then head over to the latest v4.x.x release.
On the Releases page, it seems that (at time of publishing) express@4.16.3
is the latest tagged release. By opening up the tree for the 4.16.3 tag, we can check out the package.json
:
On line 43, we see that the fresh
module is up to date at fresh@0.5.2
– the version mentioned in NCM Desktop as the safe version!
If we update Express to express@4.16.3
and npm install again, you’ll notice some changes in NCM Desktop:
By applying the "Removed" filter, we can actually see that four vulnerable modules that were introduced by Express were removed. If we look at the “Added” filter, we’ll see that there are no further vulnerabilities introduced by Express:
Yay! We erased four more vulnerabilities with a simple upgrade, thanks to about ~5 minutes of work and the new dependency chains feature in NCM Desktop Beta 3.
General Advice: What Else Can You Be Doing?
In building out this release, we noticed that this was a relatively common issue – an old and vulnerable/unpatched dependency introduced a suite of other security and compliance issues.
In addition to using NCM Desktop with your NodeSource Account, there are a few other good precautions you can be taking to ensure your time spent triaging issues is as minimal as possible:
Using automated tools like Greenkeeper can help ease this pain by consistently keeping your dependencies up to date via GitHub, eliminating a lot of the stale and old dependencies that can slip your attention over time.
Additionally, when working on publishing your code using something like Semantic Release with the @semantic-release/git plugin will help smooth out several common best practices and NCM Desktop criteria, including one of the most commonly missed: git tagging.
Use a single linter for your entire team. We use Standard at NodeSource, but using a common linter across all of your projects will save you an immense amount of time and help you ship solid software that has a smaller surface area for security issues to surface.