Malicious npm Package Exfiltrated Environment Variables at Build Time

A typosquatted npm package installed via a developer's local npm install exfiltrated AWS credentials from CI environment variables.

Overview

A one-word typo pulled in a typosquatted npm package whose install script sent CI's AWS keys to an attacker, who then swapped the site's JavaScript bundle for 6 hours.

What happened

Setting up a new project, a platform developer typed npm install lodash-utils instead of lodash. The package had been published to npm 3 weeks earlier. The developer also added it to the project's package.json without noticing it was not lodash.

How it spread

The postinstall script read process.env, serialized it and sent it to an external endpoint over HTTPS. On the developer's laptop that exposed only a development AWS_PROFILE. In GitHub Actions, the runner had deployment keys in its environment.

  • Developer's machine — AWS_PROFILE for development — Little of interest
  • CI runner (GitHub Actions) — Deployment access keys — Keys with S3 read/write and CloudFront invalidation stolen

The fix

Stop install scripts from running in CI, and make any key they could reach short-lived and narrow.

Key concepts

Typosquatting
Publishing a malicious package under a name that closely resembles a popular legitimate package, relying on developers mistyping the package name.
Postinstall script attack
Malicious npm packages that execute arbitrary code via the postinstall lifecycle hook, which runs automatically during npm install.
Lock file integrity
package-lock.json or yarn.lock files pin exact package versions and checksums, preventing unexpected package substitution.
OIDC for CI credentials
Using OpenID Connect to issue short-lived, scoped tokens to CI jobs rather than long-lived access keys stored as secrets, limiting the blast radius of a credential compromise.

When to use it

  • Discussing software supply chain security and npm package hygiene
  • Justifying the use of npm audit, lock files, and private registries
  • Explaining why CI environment variables should be scoped to specific jobs and not available to all steps

Interview questions

  • How do you protect CI/CD pipelines from malicious npm packages?

Sign up free to read the full topic

More War Stories topics

Start free on Cariara · Coding problems · System design studio