npm Blog (Archive)

The npm blog has been discontinued.

Updates from the npm team are now published on the GitHub Blog and the GitHub Changelog.

Community questions following the eslint security incident

Following the eslint incident on July 12, 2018, the community reached out to us with a few follow-up questions. This post will answer those questions as well as provide some additional technical insight into the eslint-scope malware that we haven’t seen discussed elsewhere:

Have you scanned the packages in the registry for the malicious code found in the eslint-scope package?

Both npm and RunKit performed a search for code similar to what was used during the eslint incident. Their analysis is posted here.

Have you found any other packages?

We have not found any other malicious packages with an identical payload to that of the eslint-scope malware, but we found variants. We identified 2 other packages (one on 7/13 and one on 7/16) that attempted to replicate the behavior of the eslint-scope payload. The npm security team unpublished them immediately upon discovery. Because these packages were not tied to a popular package, they received no downloads beyond downstream mirrors.

What measures have you planned for the future to prevent incidents like this?

The two packages mentioned above were discovered by our internal tooling which looks for malicious packages and suspicious behavior. We will continue to improve upon these tools as well as our response processes to reduce the time that malicious code lives in the npm Registry. 

Where it makes sense, we’ll work to extend these tools to our users to empower them to make better decisions around what packages they should use and provide context around how they were published.

Do you have any advice on how to prevent this, apart from 2FA?

Package maintainers have a lot of responsibility to the community they serve. A package maintainer should:

Additionally, maintainers should pay attention to the emails that we send out when publications happen and contact support should something seem out of place.

Install Scripts

For users that are concerned about install scripts, you can block install scripts from running with the --ignore-scripts flag.

Example: npm install --ignore-scripts

If you wish to never run scripts at install time, you can instead run the following command. However, be aware that some modules require install scripts to install properly:

npm config set ignore-scripts true

One thing to note is that if we took away install scripts, which is a popular suggestion after these types of incidents, attackers would move their payloads inside the package code, which you would likely execute as soon as you were done installing.

More Mitigating factors

During our technical analysis of the eslint-scope payload we found a critical assumption in the attacker’s code that limited its effectiveness against some users.

At first glance, the attacker’s payload was designed to grab tokens from the end of the line that looked like //registry.npmjs.org/:_authToken= in the users .npmrc file, put them in a referrer header, and send them off to a remote server.

Here is the relevant snippet from the attacker’s payload:

content = fs.readFileSync(npmrc, { encoding: "utf8" });
content = content.replace("//registry.npmjs.org/:_authToken=", "").trim();

The assumption here is that the .npmrc file contains only 1 line. If any other configurations were present in this file then the referrer header would contain new line characters (which are invalid) and the request would fail, providing the attacker with no data.

Thank you to the community for sending in questions and for working with the npm Security team to keep the registry secure.