A supply chain attack compromises software before it reaches you, targeting a dependency, build tool, or update mechanism instead of your system directly. npm is a prime target because any JavaScript project can pull in hundreds of third-party packages automatically, and a single malicious or compromised package can execute code inside your environment on install.
Pithy Security | Cybersecurity FAQs – The Details
Question: What is a supply chain attack and why is npm so risky?
Asked by: Claude Sonnet 4.5
Answered by: Mike D (MrComputerScience) from Pithy Security.
Why npm’s Open Publish Model Creates Massive Attack Surface
npm hosts over two million packages. Any developer can publish one with minimal identity verification. Packages can run arbitrary scripts at install time using postinstall hooks, meaning malicious code executes the moment you run npm install, before you’ve ever imported a single line. Attackers exploit this in several ways: typosquatting (publishing lodahs hoping someone mistyped lodash), dependency confusion (uploading a public package with the same name as a private internal one to trick package managers into grabbing the wrong one), and account takeover (hijacking a legitimate maintainer’s credentials to push a poisoned update). The 2021 ua-parser-js compromise hit millions of CI pipelines within hours of a malicious version going live. The attack surface isn’t theoretical. It’s measured in production incidents.
How Transitive Dependencies Hide Malicious Code From Developers
Most developers audit their direct dependencies. Almost nobody audits their transitive ones. A typical React application pulls in well over a thousand packages when you count every dependency of a dependency. You chose maybe twenty of them. The rest came along for the ride. The event-stream incident in 2018 is the textbook case: an attacker gained maintainer access to a popular package, added a dependency that contained malicious code targeting a specific Bitcoin wallet application, and it sat undetected for weeks. MITRE ATT&CK maps this under T1195 (Supply Chain Compromise). The attack works because trust is inherited automatically. If package A trusts package B, and package B trusts package C, you’ve implicitly trusted package C without ever evaluating it.
When Lockfiles and Provenance Checks Actually Reduce npm Risk
Package lockfiles (package-lock.json, yarn.lock) don’t prevent a malicious package from being published, but they do pin exact versions and checksums so your build doesn’t silently upgrade to a compromised release. That’s meaningful protection against the “malicious update” attack pattern. GitHub’s npm provenance feature, introduced in 2023, lets publishers cryptographically link a package to its source repository and build workflow. Sigstore-based signing is being adopted across the ecosystem. Combined with tools like npm audit, Socket.dev’s real-time package analysis, and Snyk’s dependency scanning, defenders now have real options. None of these are silver bullets. But a team that enforces lockfiles, runs audit in CI, and reviews new dependencies before adding them is meaningfully harder to hit than one that doesn’t.
What This Means For You
- Audit your
package.jsonand lock files regularly usingnpm auditor a dedicated SCA tool like Snyk or Socket.dev to catch known-malicious or vulnerable packages before deployment. - Enable provenance verification for packages you publish and check provenance data for critical dependencies where it’s available.
- Restrict
postinstallscripts in your CI environment usingnpm install --ignore-scriptsfor dependency-only installs where build scripts aren’t required. - Monitor for dependency confusion risk by ensuring your private package names are also registered on the public npm registry to prevent attackers from claiming them.
Related Questions
Want Cybersecurity Breakdowns Like This Every Week?
Subscribe to Pithy Security (Free) → pithysecurity.substack.com
