tl;dr - Update to npm v6.13.4 as soon as possible on all your systems to fix a vulnerability allowing arbitrary path access.

The Vulnerabilities

In versions of npm prior to 6.13.3 (and versions of yarn prior to 1.21.1), a properly constructed entry in the package.json bin field would allow a package publisher to modify and/or gain access to arbitrary files on a user’s system when the package is installed.

In versions of npm prior to 6.13.4 (and all versions of yarn as of this announcement), it was possible for a globally-installed package with a binary entry to overwrite an existing binary in the target install location. (That is, not any arbitrary file on the system, but any file in /usr/local/bin.)

A mitigating factor for both vulnerabilities is that a malicious actor would have to get their victim to install the package with the specially crafted bin entry. However, as we have seen in the past, this is not an insurmountable barrier.

Current Risk

The npm, Inc. security team has been scanning the registry for examples of this attack, and have not found any published packages in the registry with this exploit. That does not guarantee that it hasn’t been used, but it does mean that it isn’t currently being used in published packages on the registry.

We will continue monitoring, and will take action to prevent any bad actors from exploiting this vulnerability in the future. However, we cannot scan all possible sources of npm packages (private registries, mirrors, git repositories, etc.), so it is important to update as soon as possible.

The Fix

The package.json parsing libraries in use in npm v6.13.3 were updated such that they would sanitize and validate all entries in the bin field to remove leading slashes, . and .. path entries, and other means of path escape, using the well tested and highly reliable path utility built into Node.js.

The fix was reviewed by npm, Inc.’s security team, and showed that it prevented the arbitrary path manipulation reported.

The bin script linking libraries in use in npm v6.13.4 were updated such that, when installing binary entries of top-level globally installed packages, they will only overwrite existing binary files if they are currently installed on behalf of the same package being installed. For example, npm install –global foo could overwrite /usr/local/bin/foo if and only if /usr/local/bin/foo is currently a link to a previously installed version of foo.

This second fix was also reviewed by npm, Inc.’s security team, and showed that it prevented the bin file overwriting exploit.

To patch both vulnerabilities, please run npm install -g npm@6.13.4 as soon as possible.

Thank you!

The vulnerabilities were responsibly reported by Daniel Ruf, and we greatly appreciate Daniel’s help in keeping our community safe.

If you think you’ve found a security issue in the npm CLI, we encourage you to report it to security@npmjs.com and we’ll help you through the triage and disclosure process.