A web of interconnected nodes representing packages and dependencies. The nodes are color-coded in neutral tones, a few in red to show compromised or risky packages. Lines connecting nodes show the deep dependency chains typical of npm. npm supply chain security

npm Supply Chain Security: Understanding JavaScript Dependency Risks

TL;DR:
npm supply chain security keeps failing because the problem is structural, not procedural. Deep dependency trees, install-time code execution, and permissive versioning make the ecosystem hard to secure. As JavaScript underpins more critical systems, organisations must decide how much foundational risk they’re willing to accept.

Table of Contents

Recent npm supply chain attacks have followed a familiar pattern.
A maintainer account is compromised. A popular package is poisoned. The impact cascades through thousands of downstream repositories. Security advisories follow. The industry responds with reminders to audit dependencies, enable MFA, and strengthen governance controls.

And then it happens again.

The recurrence of these incidents suggests a deeper problem than hygiene or compliance. When the same class of attack succeeds repeatedly within the same ecosystem, the issue is structural.

In this blog, I explore why JavaScript’s npm ecosystem presents a uniquely difficult supply-chain security challenge, why traditional governance approaches struggle to contain that risk, and why organisations should reassess how much critical infrastructure they are comfortable building on top of it.

 

A timely reminder: architectural vulnerabilities in Javascript

As this piece was being finalised, a critical vulnerability affecting React Server Components surfaced, with significant impact on Next.js, one of the most widely used frontend frameworks in production today.

This was not a coding error in an application, nor a misconfiguration by end users. It was an architectural-level issue in a foundational layer of the JavaScript ecosystem.

Incidents like this reinforce an uncomfortable reality: as JavaScript frameworks become more powerful and more deeply embedded in enterprise systems, the blast radius of architectural weaknesses increases accordingly.

 

Why npm is structurally vulnerable

It is tempting to attribute npm supply chain attacks primarily to popularity. Large ecosystems attract attackers. There is some truth to that.

However, popularity alone does not explain the frequency or scale of npm-related incidents. Architecture matters.

Several characteristics of npm combine to create an unusually large attack surface.

Partial transitive dependency tree for body-parser, a core dependency of Express.js. - npm supply chain security

Figure 1 Partial transitive dependency tree for body-parser, a core dependency of Express.js.

1. Extreme dependency depth in the npm ecosystem

npm encourages micro-packages and deep transitive dependency trees. It is common for a single application to rely on hundreds or thousands of packages, many of which are small utilities maintained by a single individual.

A compromise in a low-level dependency can propagate silently into millions of downstream builds. Other ecosystems experience dependency risk, but rarely at this scale or depth.

2. Install-time code execution: a critical npm security risk

npm lifecycle scripts (preinstall, install, postinstall) allow arbitrary code execution during package installation.

This dramatically expands the attack surface. Installing a dependency is not just downloading code; it is executing it.

Most other major package ecosystems deliberately avoid this model. NuGet, Cargo, and Go Modules do not permit arbitrary install-time execution by default, precisely because of the security implications.

3. Low-friction publishing 

Publishing to npm is intentionally fast and lightweight. Historically, this included limited identity verification and optional MFA.

That ease of publishing is a strength for experimentation, but it also means account compromise can quickly translate into ecosystem-wide impact.

4. Versioning and update culture

JavaScript projects often use permissive version ranges (^, ~) and automated dependency updates. This accelerates innovation, but it also accelerates malicious propagation when a compromised version appears.

The window between publication and widespread adoption is often measured in minutes.

5. Non-deterministic dependency resolution

npm’s dependency resolution and flattening historically made reproducible builds difficult. While tooling has improved, the ecosystem still lacks the strong guarantees provided by systems such as Cargo.lock, Go’s checksum database, or NuGet’s deterministic restore model.

Together, these characteristics make npm unusually difficult to secure through policy alone.

Figure 2 Cumulative malware packages by ecosystem for 2025. Source: veracode.com - npm supply chain security

Figure 2 Cumulative malware packages by ecosystem for 2025. Source: veracode.com

Why governance and compliance tools fail to secure npm

Many organisations respond to supply chain risk with governance controls: scanning tools, approval processes, MFA requirements, and dependency policies.

These are sensible measures. They are also insufficient on their own.

Governance works best when enforcement is possible at the platform level. In npm’s case, enforcement is largely opt-in and inconsistently applied. Critical questions are difficult or impossible to answer reliably:

  • Is every transitive dependency signed or verified?
  • Are all maintainers using MFA?
  • Has any dependency been silently republished after an account compromise?
  • What code executed during installation, and when?

 

The challenge here is not developer negligence. It is that the architecture does not provide strong enforcement points.

 

Traditional governance approaches like scanning tools, dependency approval processes, and role-based access are sensible, but not enough to fully mitigate npm supply chain security risks. For teams looking for structured, enterprise-ready guidance on building resilient cyber risk programs, our Essential 8 blog offers a useful starting point.

https://arinco.com.au/blog/cybersecurity-frameworks-unplugged-the-essential-8-part-1/

 

How npm introduces supply chain risk across other ecosystems

Even ecosystems with stronger security models are not immune.

It is increasingly common for non-JavaScript projects to invoke npm as part of their build pipelines. For example, a .NET project may restore NuGet packages, trigger an MSBuild target, and then execute npm install as part of a frontend build step.

At that moment, the stronger guarantees of the primary ecosystem are bypassed, and npm’s risk model is reintroduced.

This is not hypothetical. A recent high-profile attack demonstrated real-world spillover from npm into Maven (another ecosystem) within days.

Figure 3 Install time execution allows npm to easily compromise other ecosystems. npm supply chain security

Figure 3 Install time execution allows npm to easily compromise other ecosystems

npm supply chain risk is not a developer failure

This is not a criticism of developers

It is important to be explicit about this point.

The prevalence of npm supply chain incidents is not the result of careless developers or a lack of effort. It is the result of an ecosystem optimised for speed, flexibility, and low friction being asked to support enterprise-grade security, critical infrastructure, and global scale.

Those goals are in tension.

Why npm supply chain risk cannot be easily fixed

Many of npm’s strengths are inseparable from its weaknesses:

  • Flexibility enables rapid innovation, but undermines predictability.
  • Micro-packages encourage reuse, but explode dependency graphs.
  • Install scripts enable powerful tooling, but also arbitrary execution.
  • A “no breaking changes” ethos preserves compatibility, but locks in early design decisions.

Incremental improvements help, but they do not eliminate the underlying trade-offs.

At some point, organisations must decide whether continuing to build critical systems on top of these trade-offs is acceptable.

Rethinking JavaScript foundations for enterprise security

JavaScript has been enormously successful. It enabled the modern web and accelerated software development in unprecedented ways.

But success does not automatically imply long-term suitability.

As newer execution models such as WebAssembly mature, there is an opportunity to re-evaluate what we expect from foundational platforms: stronger isolation, clearer trust boundaries, deterministic behaviour, and security models designed for today’s threat landscape rather than yesterday’s constraints.

This is not a call for immediate abandonment, nor a prediction that JavaScript will disappear. It is a call for honesty.

A more honest conversation

For technology leaders, platform engineers, and security teams, the key question is not “How do we govern npm better?”

It is:

What level of systemic risk are we willing to accept from the foundations we build on?

JavaScript and npm are not inherently “bad”. But they do embody trade-offs that are increasingly misaligned with the demands placed upon them.

Recognising that mismatch is the first step toward building more resilient systems.

The web is maturing. Our assumptions about its foundations need to mature with it.

 

Resources

Second Sha1-Hulud Wave Affects 25,000+ Repositories via npm Preinstall Credential Theft

Threat Research Year In Review – 2025

Package Managers Comparison: Yarn, NPM, PNPM | Cookielab

Sha1-Hulud 2.0 A Multi-Stage npm Supply Chain Attack Targeting Code, Cloud, and CI/CD – Phoenix Sec…

How npm install Works? What Really Happens When You Hit Enter – DEV Community

Shai-Hulud 2.0: Guidance for detecting, investigating, and defending against the supply chain attac…

More insights

Get started on the right path to cloud success today. Our Crew are standing by to answer your questions and get you up and running.