Is your package.json safe?

topcat

Misha

Posted on October 26, 2022

Is your package.json safe?

Let's do a simple check: open any JS project that you have at hand and try to find the ^ symbol in the package versions. If you don't have one, congratulations! Otherwise, I have bad news for you.

“Compatible” versions

By default NPM saves package versions in package.json with ^ prefix in front of the version number.

^version is described as “Compatible with version” in NPM docs which means “any minor or patch version equal or higher than specified”.

The problem with such versions is that after removing node_modules and package-lock.json and running npm install some packages may be upgraded to higher patch or minor versions without you knowing it.

This shouldn't break anything because usually package developers follow semantic versioning rule saying that breaking changes can only be introduced in major version updates.

But in reality there is no guarantee that new minor version of a package wouldn't break something in your app. This happens even for well-tested and well-maintained packages with large community like Webpack (see issue #8082).

Security

But there is also a much worse problem: security risks. Imagine that a hacker gets access to the NPM account of the owner of some popular package. Publishing a patch version with malicious code would immediately make all the applications using this dependency (or even package that depends on this dependency) vulnerable. You can easily find examples of such attacks by googling 'npm package hack', here is one of them: DeFi Exchange dYdX NPM User Account Gets Hacked

How to fix the problem

  1. Add save-exact=true to your package.json. This would make npm install specific versions of the packages that are used in your project.
  2. Remove ^ signs from the package versions in package.json. Or replace this inexact versions with actual versions of installed packages. You can find them in package-lock.json.

But there is a simpler solution: a CLI tool called exactify.

I've created it to automate the process of replacing “compatible with” versions with exact versions of installed packages taken from package-lock.json. It also adds save-exact=true to your .npmrc file which forces NPM to save exact versions for further package installations.

Just type npx exactify in the root of your project and see what happens!

Thank you for reading

Let me know if you found this useful. If you have any suggestions, feature requests or bug reports, feel free to fill an issue or open a PR on GitHub. Stars are kindly appreciated!

Thank you for reading! Don't forget to hit the like button and leave a comment bellow ✨

💖 💪 🙅 🚩
topcat
Misha

Posted on October 26, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related