Fixing security vulnerabilities in your npm dependencies

Monday, March 29, 2021

Command line terminal code responding with 5 security vulnerabilities after running an npm install.

Resolving Node Package Security Issues

If security were all that mattered, computers would never be turned on, let alone hooked into a network with literally millions of potential intruders. – Dan Farmer

Find a quick summary and a link to a gist below the article.

📦npm: Nice playground, Microsoft.

The plethora of packages hosted on is one of the greatest resources in today’s open source software (OSS) communities. It is available to anyone with a command-line terminal, and the free Node.js JavaScript runtime. While the node packages we have come to rely on as developers are generally open source, it is important to note that is a subsidiary of GitHub, which is of course owned by Microsoft. Private, paid hosting for teams and companies is a part of the business model.

Why am I beginning with this little explainer?
As developers, you probably know this part already, right? Let it serve as a simple reminder that most OSS is largely built on a foundation of unpaid labor. Packages need to grow, evolve and pivot in response to developer needs. Then there are the critical security risks to account for, which can expose you and your app’s users to exploitation.

🔍found 7 vulnerabilities (3 low, 2 moderate, 2 high)

So let’s say I have a brilliant app idea. I’ve wireframed some frontend basics, and chosen a stack to leverage. Time to fire up the command line, cd into my cool_new_app directory and work some npm magic!✨

$ npm i new-js-framework-of-the-week

The package manager does it’s thing for a while. My new Mac chews through it like a snack, while my aging PC is kind enough to let me grab a coffee and contemplate life. Anyway, back at the keyboard I see the results:

added 920 packages from 431 contributors and audited 923 packages in 14.897s

some of these poor devs would like money for food
	run `
npm fund
` for details

Sure, one of these days I’ll tip someone. Sadly, today is still not that day.

Wait a minute, what is this?

found 7 vulnerabilities (3 low, 2 moderate, 2 high)
	run `
npm audit fix
` to fix them, or `
npm audit
` for details

Vulnerabilities? That won’t do!

🛠Let’s fix this!

I am no security expert, but shipping code that is free of known vulnerabilities is literally doing the bare minimum. The package manager offers some helpful advice so I’ll start there. After running npm audit fix , I’ve made some headway but there are still issues:

fixed 5 of 7 vulnerabilities in 923 scanned packages

Seems I still have two leaky dependencies in my node_module , so it’s time for a simple npm audit to isolate the culprits:

		=== npm audit security report ===
# Run  npm install stale-pack@3.2.1  to resolve 1 vulnerability

Moderate	Prototype Pollution

And on it goes, with details about what packages depend on the vulnerable packages. It’s time to reach in to our toolbox for some better solutions.

npm update

Having installed and audited my dependencies, here is my next fix attempt:

npm update

This simple command will scan for any packages that are behind the current public version on and, you got it, update them. This quick command will fix many vulnerabilities in one pass. If you want to know what it is up to before you update, you can run npm outdated to see a full list of old packages.


It is possible at this point that I still have lingering vulnerabilities in nested dependencies. If I do, tilde and caret dependencies can respond in unexpected ways to npm update , so that might not be a good fix. Alternatively, maybe I want to be on a specific older version of a top-level dependency that is still safe and secure. In these cases, what should I do?

I could try updating each vulnerable package one at a time, or I could rely on a powerful package that targets nested dependencies; npm-force-resolutions. This will be added to our installation process via a script in the package.json :

  "scripts": {
    "preinstall": "npx npm-force-resolutions",

However, I need to provide some context for this module in my package.json :

 * Here I denote the latest versions,
 * but you could use caret or tilde
 * as needed. Check the docs!
  "resolutions": {
    "bad-pack-1": "1.5.0",
    "bad-pack-2: "2.0.0

Follow this pattern for each of the suspect packages. Now I can go back to the terminal and run a fresh npm install and npm-force-resolutions will run, fixing the nested dependencies!🌈

Do take a minute to read the docs on this package, and consider if this approach works for your app, and whether you should file an issue with the top-level dependency.

Thanks for checking out my first post on DEV!
Enjoy this post? How about sharing a Tweet to spread the love!

As promised, a quick summary:

/* 1. lean on npm to fix issues */
npm audit fix

/* 2. re-audit to find stubborn issues */
npm audit

/* 3. if using the latest packages is fine, update your top-level dependencies */
npm update

/* 4. if all else fails, force resolutions by adding this to package.json and doing another install */
  "scripts": {
    "preinstall": "npx npm-force-resolutions",
  "resolutions": {
    "bad-pack-1": "1.5.0"

View this as a gist on GitHub.

This post is also available on DEV.