Supply Chain Attacks

The npm 'everything' Package Attack (2024) Analyzed

In January 2024 a developer published npm packages that depended on every public npm package, triggering a denial-of-service style incident across the registry.

Shadab Khan
Security Engineer
7 min read

In January 2024 a developer named Patrick Laborde published a set of npm packages under the name everything that collectively declared dependencies on every public package on the npm registry. The project was not malware in the traditional sense. It was a demonstration that the policies npm had been tightening since the left-pad incident in 2016 still produced edge cases that could degrade the registry for other maintainers. For a brief window, any package that had been pulled into the everything tree could no longer be unpublished without GitHub's manual intervention, because npm's 72-hour unpublish rule excludes packages with dependents.

The incident forced GitHub's npm team to publicly clarify how the unpublish policy interacts with synthetic dependency graphs, and it reopened a long-running argument about whether a registry should host packages that exist only to stress-test its own rules. For engineers shipping production JavaScript, it also surfaced a subtler question: how confident are you that your lockfile is not accidentally pulling in a package that was published as a joke, a protest, or a proof of concept?

What exactly did the 'everything' package do?

The everything package and its sibling @everything-registry/* scoped packages declared, through a chain of sub-packages, a dependency on every package published to npm at the time of the 2024 crawl. Installing everything did not, in the typical sense, run malicious postinstall scripts. It simply forced npm's resolver to consider and download every reachable package in the public registry, which on a cold cache meant hundreds of gigabytes of downloads and tens of minutes to hours of install time depending on network and disk.

The packages were organized into a tree because the npm manifest format does not accept unbounded dependency lists cleanly, and because splitting the graph made it more obvious to GitHub's abuse pipeline that the intent was structural rather than functional. The README on GitHub framed the project as a joke and a test of registry limits.

Why did npm struggle to remove it?

npm struggled to remove it because its own unpublish policy explicitly prevents maintainers from unpublishing a package that has other packages depending on it after a 72-hour grace window. That rule exists because of left-pad: when Azer Koculu unpublished left-pad in 2016, thousands of downstream builds broke worldwide, and npm tightened unpublish controls in response. The everything package weaponized that rule by creating a dependency edge from itself to every other package, meaning any maintainer who tried to unpublish their own package after the 72-hour window now saw a refusal citing everything as a dependent.

Resolving this required GitHub staff to delete the offending packages manually and, according to follow-up posts by the npm team, to adjust internal tooling to ignore abusive dependents when evaluating unpublish eligibility. The incident was a reminder that registry policies are adversarially testable.

Did anyone actually install it in production?

Almost nobody installed it in production, but telemetry from several SCA vendors showed a non-trivial number of curious developers installing it into personal sandboxes and CI environments that then exceeded their disk quotas. More importantly, several package maintainers reported that their own npm unpublish commands failed during the window when the everything tree was live, because their package had been absorbed into its dependency graph. That is a production impact even if the everything package itself never reached a production artifact.

The takeaway for organizations that allow unrestricted installs from the public npm registry is that a package does not need to be malicious to be disruptive. Install-time side effects, whether intentional or incidental, can hit CI runners, developer laptops, and storage infrastructure.

How is 'everything' different from a typical dependency-confusion attack?

The everything package is different from a dependency-confusion attack because it does not impersonate an internal package, and it does not attempt to exfiltrate data or execute code on install. Dependency-confusion attacks, popularized by Alex Birsan's 2021 research against Apple, Microsoft, and others, rely on the resolver preferring a higher-version public package over a lower-version private one with the same name. The everything attack instead targeted the registry's governance surface, specifically the unpublish API and its dependent-check.

Both classes of incident, however, share a common root cause: npm's default trust model assumes that names in the public registry are cooperatively managed. When a single actor can publish thousands of packages in a coordinated burst, or can claim names that collide with private scopes, the registry's implicit assumptions break.

What did GitHub and npm change after the incident?

GitHub and npm changed several things after the incident, though not all of them are publicly documented. Publicly, the npm team acknowledged in follow-up posts that they accelerated work on abuse detection for bulk-publish patterns, tightened rate limits on the publish API, and updated internal runbooks so that maintainer unpublish requests blocked by adversarial dependents could be escalated quickly. The 72-hour unpublish window itself was not removed, because the left-pad lesson still applies, but the handling of edge cases was clarified.

Separately, the ecosystem saw renewed interest in tools that can statically answer the question, "what does this package actually touch at install time and at runtime?" The everything tree was trivially detectable by any tool that flags unusually large dependency graphs, but many organizations had no such check in place.

What should engineers do about registry-level risks like this?

Engineers should do three concrete things about registry-level risks like this. First, pin dependencies in lockfiles and review lockfile diffs in pull requests with the same seriousness as source-code diffs; a single npm install in a branch can introduce dozens of new transitive packages. Second, constrain what the install process is allowed to do, by disabling lifecycle scripts where possible (npm install --ignore-scripts), sandboxing CI builds, and enforcing network egress policies on build runners. Third, use a curated registry or registry proxy that mirrors only vetted packages, so that a future everything-style incident cannot reach your builds until a human has approved it.

These steps are not novel and most of them appear in OpenSSF's Concise Guide for Developing More Secure Software, but they continue to be inconsistently adopted. The everything incident is a reminder that registry governance is a shared resource and that defense-in-depth on your side of the boundary matters.

Does this still matter in 2026?

This still matters in 2026 because the structural conditions that made the everything incident possible have not fundamentally changed. The npm registry still accepts bulk publishes from any account. The unpublish rules still depend on dependent-graph state. Registry proxies, policy engines, and SBOM tooling have all matured, but adoption is uneven, and most organizations still install directly from the public registry on every build.

The follow-on research in 2024 and 2025 into slopsquatting, typo-squatting at scale, and maintainer-account takeovers all build on the same underlying insight: the registry is a shared trust surface, and every organization inherits the aggregate risk of every decision made by every maintainer and every abuse pipeline. The everything package was a relatively benign demonstration. The next one may not be.

How Safeguard.sh Helps

Safeguard.sh uses reachability analysis to cut dependency-graph noise by 60 to 80 percent, so a package absorbed into a synthetic tree like everything does not drown your alerts queue. Griffin AI performs autonomous remediation, opening pull requests that pin, replace, or remove risky transitive dependencies before they reach CI. Eagle classifies packages as malicious, suspicious, or clean using behavioral signals rather than name matches, flagging registry-abuse patterns that do not fit traditional malware signatures. The Gold registry provides a curated mirror of vetted packages, combined with SBOM generation at a dependency depth of 100 levels and container self-healing that rebuilds images when upstream packages are pulled or flagged.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.