How to check for dependency security issues in your package.json

Published on

We often blindly npm add some-package, and its still there years later in our repo.

There are a lot of issues with blindly adding dependencies to our package.json file. Here is a list of some things you can do to minimize the risk:

npm outdated

Run the npm outdated command to get a table of outdated components.

% npm outdated
Package                          Current   Wanted   Latest  Location                                      Depended by
@babel/core                       7.16.0  7.20.12  7.20.12  node_modules/@babel/core                      your-package-name 2023
@babel/plugin-transform-runtime   7.16.4   7.19.6   7.19.6  node_modules/@babel/plugin-transform-runtime  your-package-name 2023
@babel/preset-env                 7.16.4   7.20.2   7.20.2  node_modules/@babel/preset-env                your-package-name 2023
@mailchimp/mailchimp_marketing    3.0.72   3.0.80   3.0.80  node_modules/@mailchimp/mailchimp_marketing   your-package-name 2023
@next/bundle-analyzer             12.0.3   12.0.3   13.1.5  node_modules/@next/bundle-analyzer            your-package-name 2023
@tailwindcss/forms                 0.3.4    0.3.4    0.5.3  node_modules/@tailwindcss/forms               your-package-name 2023
...

npm audit

Run npm audit to go through your package.json and tell you about security issues, and their severity.

You can also fix it with npm audit fix to try and install more recent versions.

# npm audit report

cookiejar  <2.1.4
Severity: moderate
cookiejar Regular Expression Denial of Service via Cookie.parse function - https://github.com/advisories/GHSA-h452-7996-h45h
fix available via `npm audit fix`
node_modules/cookiejar

Use package.lock (or yarn.lock) correctly

The lock files (package.lock for npm, yarn.lock for yarn) can be used to lock down to a specific version of a dependancy.

You might specify a version of ^7.29.0, but the actual version installed on your machine is 7.31.0. With package.lock you can ensure that any other installations of your codebase will use the file specified in your lock file.

Your lock file should be committed to git.

Info from npm docs:

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

use npm shrinkwrap

This command repurposes package-lock.json into a publishable npm-shrinkwrap.json or simply creates a new one. The file created and updated by this command will then take precedence over any other existing or future package-lock.json files.

difference between shrinkwrap and package-lock

package-lock.json vs npm-shrinkwrap.json Both of these files have the same format, and perform similar functions in the root of a project.

The difference is that package-lock.json cannot be published, and it will be ignored if found in any place other than the root project.

In contrast, npm-shrinkwrap.json allows publication, and defines the dependency tree from the point encountered. This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages.

If both package-lock.json and npm-shrinkwrap.json are present in the root of a project, npm-shrinkwrap.json will take precedence and package-lock.json will be ignored.

update dependencies with npm update

Run npm update to update your dependencies to the latest version, according to your package.json.

Examples (pretend there is a package with versions 1.0.0, 1.0.1, 1.1.1, 1.1.2, 1.2.0, 2.0.0

  • Your package.json has a dependency set to ^1.0.0. Your current version is 1.1.1. Running npm update could update to 1.1.2 or 1.2.0, (it will pick the highest)
  • If it is set to ~1.0.0 then it will update only to 1.1.2

all example outputs are from an older test project