The eslint-scope Supply Chain Attack

Updated 5 Oct 2026 · Incident date 12 Jul 2018 · npm

Packageeslint-scope 3.7.1 -> 3.7.2 (and eslint-config-eslint 5.0.1 -> 5.0.2)
Filelib/build.js

The npm packages eslint-scope 3.7.2 and eslint-config-eslint 5.0.2 contained malicious code. They were live on 12 July 2018 from 9:49 UTC to 12:37 UTC, about three hours. Version 3.7.1 was clean.

The code read the .npmrc file and sent the npm tokens it held to an attacker.

What happened

An attacker used the npm account of an ESLint maintainer. The ESLint postmortem says the maintainer had reused the npm password on other sites and had no two-factor authentication. The attacker found the password in a third-party breach and created an authentication token.

The attacker published the two packages with a malicious postinstall script. The script downloaded code from pastebin.com and ran it. That code sent the contents of the user's .npmrc file to the attacker. The .npmrc file usually holds npm publishing tokens.

The postmortem says eslint-scope is a dependency of several popular packages, including some older versions of ESLint and the latest versions of babel-eslint and webpack at the time. The GitHub advisory says the code sent tokens to two remote servers.

npm revoked all tokens issued before 12:30 UTC on 12 July 2018. The malicious packages were unpublished, the Pastebin link was removed, and version 3.7.3 of eslint-scope was published from the 3.7.1 code.

Affected versions

Version 3.7.1 of eslint-scope was clean. The advisory lists 3.7.2 as the affected release. A machine is exposed if it ran npm install and fetched 3.7.2 in the three-hour window.

Indicators of compromise

How to check

List the installed version.

npm ls eslint-scope eslint-config-eslint

Search lockfiles for the bad version.

grep -rn -A1 '"eslint-scope"' package-lock.json | grep 3.7.2

You can also look for a postinstall script in the installed package.

grep -n postinstall node_modules/eslint-scope/package.json

What to do now

  1. Update eslint-scope to 3.7.3 and eslint-config-eslint to 6.0.0 or later.
  2. Revoke all npm tokens that were on any machine that installed the bad version, and create new ones.
  3. Check the packages you publish for versions you did not release.
  4. Use a unique password and turn on two-factor authentication for npm.

Vigilance compares the version you trust with a new one and reports the file that gained a new capability. Here the package gained a postinstall script, a remote fetch and a token read. See all attacks.

What Vigilance showed

Vigilance compares the version you trust with the new one and names the file that gained a new capability. The block below is rebuilt from the public reports in the words Vigilance prints. It is not a captured scan, because the malicious release is not redistributed.

vigi diff --old eslint-scope-3.7.1 --new eslint-scope-3.7.2
files scanned: 58 (1 Added)

HEADS UP  1 file can now do things the old version could not. The rest changed and gained nothing.

NEW FILE   lib/build.js
           It runs a command on its own when it is installed, downloads from the internet and reads saved passwords and access keys.

Frequently asked questions

Which eslint-scope version was malicious?

Version 3.7.2, along with eslint-config-eslint 5.0.2. They were live for about three hours on 12 July 2018. Version 3.7.3 is the clean replacement.

How did the eslint-scope attack happen?

An attacker used a maintainer's reused password, found in another breach, to publish packages with a postinstall script that stole npm tokens.

Sources

  1. eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes/
  2. github.com/advisories/GHSA-hxxf-q3w9-4xgw

More supply chain attacks

All 111 attacks in the library · npm supply chain attacks · How to prevent supply chain attacks

Check the next update before you install it

Vigilance compares the version you trust with the new one. It names the one file that can now do something it could not do before.

Start Free