The vast majority of packages are safe… but, some aren’t. And, some packages that used to be safe can become compromised. Even in a safe neighborhood, it’s best to lock your car.
In the following post, we take an application security expert’s point of view at good practices and behaviors you should be doing whenever you start a project as well as on a [good] cadence throughout the life of your projects.
The Dependency Iceberg
Fig. 1. Iceberg; not to scale
What can be done, then, to steer safely clear of potential danger? The answers depend on where you are in the lifecycle of your project.
At the beginning of your project and any time you add a new dependency, choose your dependencies carefully. As an ongoing part of development throughout the life of your project, update your dependencies responsibly.
Use the package rating metrics and social cues available on the npm package page. High scores for popularity, quality, and maintenance are strong signals that a package is suitable for use.
Fig. 2. package quality metrics
Review the version history of the package to ensure a healthy release cadence has been established by the package maintainers. A slowing or stalled release cadence or a shift in project personnel may be a sign of maintainer fatigue. Maintainer fatigue can make it easier for unscrupulous actors to take control of projects through social engineering. When maintainers have poured years of heart, soul, and sweat into a project for no money and little community support, an offer to switch control to a new party may be too tempting to invite thorough vetting before handing over the keys. While not common, custody transitions have resulted in malicious code entering once-trusted libraries and could certainly happen again.
Review npm Advisories and Use
When you install a package from the public registry, npm will report any security vulnerabilities:
npm audit to check the vulnerability status of your candidate dependency set:
If there’s a vulnerability, read the advisory to judge whether or not it’s a show-stopper and if there are patched versions available.
Pin Dependencies as Narrowly as Possible
When you install a dependency without specifying a version, npm installs the latest version and sets the dependency package.json to ^x.y.z––which will automatically update the dependency to the latest minor version within the scope of the specified major version whenever you perform a fresh install or
The minor-version range provided by this default behavior strikes a balance between safety and reproducibility on the one hand and the benefits of bug-fixes and on the other. How wide or narrow to pin dependencies is by no means a settled issue, but from a security perspective, the narrower the better.
Also, commit your package-lock.json file to source control. This will ensure that all transitive dependencies are pinned, as well.
As your project matures, establish a steady tempo of updating your dependencies. If you update too slowly, you may miss important security updates and expose yourself to a widening window of vulnerability. If you update too aggressively, you don’t give the ecosystem’s immune system time to react to potential malware. Aim for the goldilocks zone when establishing your update tempo.
Don’t automatically install random stuff from the Internet. Before committing to a dependency update, check to see if there are any security advisories for it. In addition to showing a history of security advisories for all packages,the advisories page on npmjs.com supports searching for advisories on particular packages, e.g.:
You can also pull a package down for further inspection without installing and/or install without running install scripts, then perform npm audit.
To install without running package scripts, run:
npm install --ignore-scripts
You can do this in a test/dummy project to avoid accidentally installing an unexpected package into a working project.
To run an audit without installing anything, run:
npm install --package-lock-only
What We Do Behind The Scenes
Ultimately, the practices of choosing, using, and updating open source software responsibly can only be done by the dependent application developer. But, there is much activity happening behind the scenes at npm to keep the registry safe.
Perhaps the most important thing we do, though, is to respond quickly to vulnerability reports from the community and alert the maintainers when there’s an issue so a patch can be issued. Like a neighborhood watch program, the vigilance of the entire community is critical to the continued safety and usability of our shared resources.
Open source software contributions do not come only in the form of code commits. If you find a vulnerability in a published package, you can do your part by reporting it to us so others can benefit from your research. We take immediate action on such reports to investigate the nature and extent of the vulnerability as well as to notify maintainers to give them time to fix the issue before disclosing it to the public and removing any vulnerable packages from the registry as necessary.
You can report vulnerabilities here:
or by emailing email@example.com
Do You Have a Headache Yet?
npm Enterprise can help. Learn how npm Enterprise automatically ensures security and compliance ›