Source-linked AI summary
Small World with High Risks: A Study of Security Threats in the npm Ecosystem
Markus Zimmermann, Cristian-Alexandru Staicu, Cam Tenny, Michael Pradel
TL;DR
npm’s open, heavily reused package ecosystem creates security risks because dependencies, maintainers, and published vulnerabilities can affect many downstream users. The paper systematically analyzes package dependencies, maintainers, and publicly reported issues, finding broad single points of failure and persistent vulnerable dependencies while evaluating targeted mitigations.
Problem
The paper asks whether npm incidents involving package removal and malicious releases reflect a broader security problem in the densely connected ecosystem.
Method
The study analyzes dependency graphs and their evolution, package maintainers, and publicly reported security issues across millions of package versions.
Results
The results show that individual packages can affect large ecosystem regions, a few maintainer accounts could inject malware into most packages, and many packages depend on publicly vulnerable code.
Takeaways & Limitations
Trusted maintainers and code vetting for selected packages could significantly reduce current npm security risks, although securing every package is infeasible.
Takeaways & Limitations
The vulnerable-code reach metric covers publicly known vulnerabilities rather than all vulnerabilities present in npm modules.
Abstract
from arXiv · showhide
The popularity of JavaScript has lead to a large ecosystem of third-party packages available via the npm software package registry. The open nature of npm has boosted its growth, providing over 800,000 free and reusable software packages. Unfortunately, this open nature also causes security risks, as evidenced by recent incidents of single packages that broke or attacked software running on millions of computers. This paper studies security risks for users of npm by systematically analyzing dependencies between packages, the maintainers responsible for these packages, and publicly reported security issues. Studying the potential for running vulnerable or malicious code due to third-party dependencies, we find that individual packages could impact large parts of the entire ecosystem. Moreover, a very small number of maintainer accounts could be used to inject malicious code into the majority of all packages, a problem that has been increasing over time. Studying the potential for accidentally using vulnerable code, we find that lack of maintenance causes many packages to depend on vulnerable code, even years after a vulnerability has become public. Our results provide evidence that npm suffers from single points of failure and that unmaintained packages threaten large code bases. We discuss several mitigation techniques, such as trusted maintainers and total first-party security, and analyze their potential effectiveness.
1 Introduction
npm’s openness and dense reuse create broad security exposure: individual packages can affect large portions of the ecosystem, while a few maintainers could inject malware widely. The study also finds substantial exposure to known vulnerabilities and evaluates targeted mitigation strategies.
- Ecosystem growth: Over 800,000 packages made npm a large source of reusable JavaScript code by February 2019.npm combines an online package database with a package manager that automatically resolves and installs dependencies.
- Security exposure: Installing an average npm package implicitly trusts 79 third-party packages and 39 maintainers, creating a large attack surface.This exposure arises through automatically installed transitive dependencies.
- Security exposure: Highly popular packages can influence more than 100,000 other packages through direct or indirect dependencies, making them potential malware-injection targets.The ecosystem’s dense dependency structure amplifies the reach of individual packages.
- Security exposure: A very small number of compromised maintainer accounts could inject malware into the majority of all packages.Some maintainers have influence over hundreds of thousands of packages.
- Known vulnerabilities: Up to 40% of all packages depend on code with at least one publicly known vulnerability.The finding concerns publicly reported security issues in package dependencies.
- Mitigation: About 140 trusted maintainers could halve compromised-maintainer risk, while vetting the top 300 packages could halve risk through code review.The paper also defines perfect first-party and third-party security and argues that highly downloaded or widely depended-on packages should pursue both.
2 Security Risks in the npm Ecosystem
npm’s security risks arise from heavy dependency reuse, weak isolation, limited systematic vetting, and several maintainer- or package-based attack scenarios. Locked dependencies can preserve vulnerable versions, while npm’s publishing and maintenance model leaves users exposed to malicious or abandoned code.
- Dependency management: Package-lock.json makes installations uniform by locking transitive dependencies, but can also preserve vulnerable versions until dependencies are deliberately updated.Without locking, installations at different times or on different machines may resolve different compatible versions.
- Ecosystem properties: npm packages often have many transitive dependencies, increasing the number of third-party components trusted by an application.Express.js transitively depends on 47 packages, compared with ten for the core of Java’s Spring web framework.
- Ecosystem properties: Micropackages expand npm’s attack surface because even tiny packages can contribute to security risk like functionality-heavy packages.The paper links this risk to excessive fragmentation of the codebase.
- Ecosystem properties: JavaScript lacks privilege separation between packages, so third-party code receives the full privileges of the application.The absence of sandboxing is especially consequential for packages running on Node.js outside a browser.
- Vulnerability discovery: npm has no systematic code-vetting process, so known vulnerabilities are mostly reported by individuals through manual analysis or focused research.The paper describes vulnerability discovery as still being in its infancy.
- Threat models: Threat models include malicious packages, privacy-violating dependencies, unmaintained vulnerable code, package takeover, account takeover, and collusion among maintainers or packages.These scenarios cover both previously observed incidents and attacks considered possible in the future.
3 Methodology
The methodology models npm as an evolving dependency graph and defines package-, maintainer-, and vulnerability-level metrics to quantify ecosystem influence and risk. It also introduces an approximate greedy strategy for estimating colluding-maintainer impact.
- Dependency data: The study constructs npm dependency graphs from package metadata, analyzing 676,539 nodes and 4,543,473 edges without downloading or installing every package.Snapshots are formed from metadata covering all published releases.
- Package metrics: Package reach counts packages with a transitive dependency on a given package, while average package reach normalizes influence across the ecosystem.The average metric addresses growth-driven increases in raw reach.
- Package metrics: Implicitly trusted packages capture the packages users trust indirectly when installing a package, complementing package-reach measurements.The methodology analyzes both the size of these sets and their ecosystem-wide average.
- Maintainer metrics: Maintainer reach combines the reaches of a maintainer’s packages, while implicitly trusted maintainers identify maintainers controlling implicitly trusted packages.These metrics expose the security relevance of human actors rather than packages alone.
- Maintainer metrics: The collusion analysis greedily selects the maintainer providing the largest local increase in package reach, approximating an NP-hard maximum-coverage problem.The strategy indicates ecosystem vulnerability but is not guaranteed to be optimal.
- Vulnerability metrics: Vulnerability reach measures packages transitively dependent on publicly vulnerable packages, while the reporting rate tracks how many vulnerable packages are known over time.The analysis uses 609 advisories affecting 600 packages and focuses on publicly reported vulnerabilities.
4 Results
The results are organized around package dependencies, maintainer influence, and unpatched vulnerabilities, covering risks from malicious code injection and legacy vulnerable code. The analysis proceeds from package-level findings to maintainer-level threats and then dependency on vulnerable code.
- Package-level risks: The results first examine package dependencies and their evolution, addressing malicious-package and package-takeover risks.This establishes how package structure can propagate security effects across npm.
- Maintainer-level risks: The study then evaluates maintainer influence, including account compromise and collusion threats.The analysis distinguishes risks arising from individual maintainer accounts from package-level reach.
- Vulnerability risks: Finally, it examines the dangers of depending on unpatched security vulnerabilities, addressing risks from unmaintained legacy code.This component concerns vulnerable code remaining reachable through package dependencies.
4.1 Dependencies in the Ecosystem
npm’s rapid growth has increased dependency complexity and package reach, expanding the ecosystem’s implicit trust and the potential impact of compromised packages.
- 676,539 packages and 199,327 maintainers comprised the measured ecosystem, with packages and maintainers increasing super-linearly over eight years.
- 4.1.1 Direct and Transitive Dependencies: 2.8 direct dependencies per average package in 2018 produced 80 transitive dependencies, showing super-linear dependency growth.Direct dependencies rose from 1.3 in 2011 to 2.8 in 2018, while transitive dependencies reached 80 in 2018.
- 4.1.1 Direct and Transitive Dependencies: Around 80 other packages become implicitly trusted when a user installs an average npm package.Dependent packages can execute installation scripts or code invoked through third-party modules.
- 4.1.2 Package Reach: 230 other packages were impacted by an average package in 2018, and package reach increased continuously since npm’s creation.
- 4.1.2 Package Reach: 24,500 packages reached at least 10 other packages in 2018, compared with 9,500 in 2015.The distribution indicates that more packages reached significant numbers of other packages over time.
- 4.1.2 Package Reach: More than 100,000 packages could be reached by some highly popular packages, making them prime attack targets.The paper states that this high-reach problem has worsened over the past few years.
- 4.1.2 Package Reach: Event-stream reached 5,466 packages, while 1,165 other packages had equal or greater reach, showing that many alternative targets existed.
- 4.1.2 Package Reach: Eslint-scope’s modified reach exceeded 100,000 packages, and 347 other packages had higher reach.The modified reach includes transitive regular dependencies and direct development dependencies for this attack analysis.
4.2 Analysis of Maintainers
Maintainer control and transitive trust expanded over time, creating concentrated attack opportunities: a small set of accounts can influence large portions of npm.
- Packages per Maintainer: Maintainers increasingly controlled more packages, with average package control rising from 2.5 in 2012 to almost 4.5 in 2018.
- Packages per Maintainer: Most maintainers operated few packages, but some controlled over 100, while the number maintaining more than one package more than tripled after 2015.
- Implicitly Trusted Maintainers: ITM nearly doubled for the average npm package in the last three years, while popular packages remained above 20 implicitly trusted maintainers.
- Implicitly Trusted Maintainers: The average npm package transitively relied on code from 40 maintainers, compared with 20 for popular packages.
- Maintainers Reach: 391 maintainers could affect more than 10,000 packages in 2018, up from 59 in 2015.
- Maintainers Reach: Twenty colluding maintainers could reach more than half of the ecosystem, after which additional maintainers added little attack performance.
4.3 Security Advisories Evolution
npm reported vulnerabilities at an increasing rate, but many advisories remained unpatched and vulnerable code continued reaching a substantial share of packages.
- Advisory Reporting: Advisories increased from two to almost eight per 10,000 packages between 2013 and 2018.
- Advisory Reporting: Two campaigns accounted for almost half of reported advisories: 141 HTTP issues and 120 directory-traversal vulnerabilities.
- Unpatched Vulnerabilities: Two out of three advisories remained unpatched, leaving users exposed to known security vulnerabilities.
- Vulnerability Reach: The reach of unpatched vulnerable code was between 30% and 40% of packages for most of the observed period.
- Vulnerability Reach: Up to 40% of all packages relied on code known to be vulnerable.
5 Potential Mitigations
The paper outlines awareness, vulnerability-warning, code-vetting, and maintainer-vetting strategies, while noting substantial implementation costs and scope limitations.
- Overview: The proposed mitigations are presented as future-research ideas with an initial assessment rather than fully developed solutions.
- Risk Awareness: npm currently omits transitive-dependency and maintainer-influence information that could help developers assess package risks.
- Vulnerability Warnings: npm audit checks direct dependencies against known vulnerabilities but misses transitive vulnerabilities, unknown issues, and malware attacks.
- Code Vetting: Vetting the top 400 packages would require analyzing over 100,000 changed lines of code per release.
- Code Vetting: Code vetting must account for platform-specific security models, such as client-side XSS versus server-side command injection.
- Maintainer Vetting: Vetting about 140 influential maintainers could halve the risk from compromised maintainers, compared with more extensive package-code vetting.
6 Related Work
Related work covers JavaScript security, dependency management, software ecosystems, and ecosystem evolution; this paper adds a detailed maintainer-centered analysis of npm security.
- Contribution: This study extends prior work by analyzing maintainers, attack impacts, and the potential impact of code vetting in depth.
- JavaScript Security: Prior JavaScript-security studies examined trivial-package use, dependency constraints, breaking changes, dependency-based attacks, and dependency isolation.
- Client-Side Security: Client-side studies measured dependency growth, vulnerable-library inclusion, and data leakage through third-party resources.
- Software Ecosystems: Software-ecosystem research identified challenges including generalizing findings across ecosystems and developing ecosystem-specific theories.
- Ecosystem Evolution: Earlier npm-evolution studies examined growth, dependencies, popularity, versioning, and vulnerability, while reporting impacts up to 30% of packages and applications.
7 Conclusions
npm’s densely connected package structure creates high security risks: vulnerable or malicious code can propagate widely, and compromised maintainers can affect many packages. The study finds that trusted maintainers and code vetting for selected packages could significantly reduce these risks.
- npm packages are densely connected, so vulnerable or malicious code in one package may affect thousands of others.
- A single misbehaving maintainer, including one with a compromised account, may have a huge negative impact on the ecosystem.
- Trusted maintainers and code vetting for selected packages could significantly reduce current security risks.