Back to blog

Protecting Against JavaScript Package Supply Chain Attacks

May 21, 2025
Blog author

Alex Bjørlig

ab@21risk.com

Protecting Against JavaScript Package Supply Chain Attacks

Modern web applications are built on top of hundreds — sometimes thousands — of open-source packages. That massive dependency tree is also a massive attack surface. In recent years the JavaScript package ecosystem has seen a sharp increase in supply chain attacks, and we have been working hard to make sure 21RISK stays ahead of these threats.

The threat landscape

Supply chain attacks exploit the trust developers place in open-source packages. Rather than attacking an application directly, adversaries compromise a dependency somewhere in the chain. Common techniques include:

  • Malicious postinstall scripts — a compromised package runs arbitrary code the moment it is installed, before any application code executes. Credentials, environment variables, and CI secrets can be exfiltrated in seconds.
  • Package hijacking — an attacker gains control of a legitimate maintainer account and publishes a new version containing malicious code. Every consumer that auto-updates is immediately affected.
  • Typosquatting — publishing packages with names that look almost identical to popular ones (e.g., lodahs instead of lodash ), hoping a developer makes a typo during installation.
  • Dependency confusion — publishing a public package with the same name as a private internal package, tricking package managers into pulling the malicious public version.

These are not hypothetical scenarios. High-profile incidents like the event-stream , ua-parser-js , and colors / faker compromises have demonstrated how damaging a single poisoned dependency can be.

How we hardened our pipeline with pnpm

We recently adopted pnpm as our package manager and configured a set of built-in supply chain protections in our pnpm-workspace.yaml :

1. Allowlisted postinstall scripts ( allowBuilds ) Only explicitly trusted packages are permitted to run postinstall scripts. If a new or compromised dependency adds a postinstall script, pnpm blocks it automatically. This single measure neutralises one of the most common attack vectors.

2. Minimum release age ( minimumReleaseAge ) Newly published package versions are quarantined for three days before they can be installed. Malicious releases are typically detected and removed from package registries within hours, so this waiting period dramatically shrinks the window of exposure.

3. Blocked exotic subdependencies ( blockExoticSubdeps ) Transitive dependencies cannot pull code from git repositories or direct tarball URLs. Only direct dependencies listed in our package.json may reference non-registry sources. This prevents a compromised subdependency from silently swapping in code from an untrusted location.

4. Trust policy ( trustPolicy: no-downgrade ) If a package's trust level drops compared to previous releases — for example, a previously trusted-publisher package suddenly loses its provenance evidence — installation fails. This catches scenarios where a package maintainer account has been hijacked and the new publisher does not meet the same trust bar.

Together these settings create multiple layers of defence that apply automatically on every developer machine and in CI.

What we are evaluating next

While pnpm gives us a strong baseline, we believe in defence in depth. We are currently evaluating two specialised tools to further harden our supply chain:

Aikido Security ( aikido.dev ) Aikido combines software composition analysis (SCA) with runtime reachability analysis. Instead of just flagging every known CVE in your dependency tree, it focuses on vulnerabilities that are actually reachable from your code. This dramatically reduces noise and helps us prioritise the issues that genuinely matter.

Socket ( socket.dev ) Socket takes a different approach by analysing package behaviour rather than relying solely on known vulnerability databases. It inspects what a package actually does — network access, filesystem operations, environment variable reads, postinstall scripts — and flags suspicious behaviour before it reaches production. This is particularly effective against zero-day supply chain attacks that have not yet been assigned a CVE.

Both tools complement our existing Snyk and Dependabot setup by catching threats that traditional vulnerability scanners miss.

Conclusion

Supply chain security is not a one-time project — it is an ongoing practice. By combining pnpm's built-in protections with continuous evaluation of specialised tooling, we aim to stay ahead of an evolving threat landscape and keep our customers' data safe. We will continue to share updates as we roll out additional protections.

To learn more about how we protect against these and other threats, see our known attack vectors documentation .