If you have ever built a website or app, there is a good chance it relies on npm — a library of over 2 million free, shared code packages downloaded billions of times every week.
For seven years, attackers have been quietly poisoning that library. Not by breaking into servers — but by tricking or compromising the individual developers who maintain those packages, then slipping malicious code inside tools that millions of people trust and install automatically.
On May 22, 2026, GitHub announced two new defenses that fundamentally change how packages get published. To understand why they matter, you need to know what happened first.
Seven Years of Attacks
Every attack below followed the same pattern: find one weak link in the chain — a tired maintainer, a stolen password, a misconfigured pipeline — and use it to push malicious code to millions of developers who trust and install it automatically.
November 2018
event-stream — A stranger offered to help maintain a popular package. The maintainer said yes. Hidden code stole Bitcoin credentials for 2.5 months, downloaded 8 million times.
February 2021
Dependency Confusion — Researcher Alex Birsan accessed internal systems at Apple, Microsoft, Uber and 30+ more companies without stealing a password — just by publishing a higher-versioned fake package. Earned $130,000 in bug bounties.
October 2021
ua-parser-js — Account stolen. 7 million weekly downloads quietly mining cryptocurrency on every install, including inside Apple, Google, Facebook, and Microsoft products.
January 2022
colors.js / faker.js — The maintainer himself broke his own packages in protest. Thousands of companies woke up to crashed apps. Not all threats come from strangers.
August 2025
Nx — Turning point: attackers stop targeting developers and start targeting their automated pipelines. A flaw in Nx's GitHub Actions workflow lets attackers steal a publishing token and push backdoored packages without fooling any human.
September 8, 2025
chalk / debug / color — One convincing phishing email from npmjs.help. One developer's password and live login code stolen in real time. 27 packages with 2.6 billion weekly downloads poisoned with a crypto wallet drainer. Live for 2 hours.
September 14, 2025
Shai-Hulud Wave 1 — The world's first self-spreading npm worm. Infects one developer's machine, finds every package they maintain, infects those too, then spreads to their maintainers. 180+ packages. 500+ touched. Named after the sandworm from Dune.
November 24, 2025
Shai-Hulud 2.0 — 700+ packages, 27,000 malicious GitHub repositories, secrets stolen from 487 companies. New feature: if you revoke the stolen token, it deletes every file on your computer.
February 20, 2026
SANDWORM_MODE — The worm learns to talk to AI coding assistants. Injects hidden instructions into tools like Claude Code and GitHub Copilot, telling them to quietly read and forward SSH keys, passwords, and cloud credentials — without telling the developer.
March 31, 2026
axios — North Korea — Attackers linked to North Korea poison axios, the most-downloaded JavaScript package in the world at 100 million installs per week. Silent backdoor deployed to ~600,000 installs in a 3-hour window. Present in ~80% of all cloud environments.
April 22, 2026
Bitwarden CLI — A password manager gets poisoned. For 90 minutes, the Bitwarden CLI package stole the very secrets it was trusted to protect — AWS keys, GitHub tokens, SSH keys, and AI tooling configs. Embedded string: "Shai-Hulud: The Third Coming."
May 11, 2026 — 19:20 UTC
TanStack — CVE-2026-45321 — 84 malicious packages in 6 minutes. Attackers hijack TanStack's own automated build pipeline — and because they used the legitimate publishing system, every poisoned package came with valid security certificates that normally prove authenticity.
May 19, 2026 — 01:56 UTC
@antv — Largest single wave — 639 malicious versions across 323 packages, 16 million weekly downloads, all in one hour. GitHub emergency response: removed 640 packages and cancelled 61,274 developer tokens — the largest mass revocation in npm's history.
May 22, 2026
GitHub ships staged publishing + install controls — The structural fix lands.
The Attacks That Changed Everything
The Email That Poisoned 2.6 Billion Weekly Downloads
npmjs.help — three days before the attack. On a phone screen, the difference from npmjs.com was nearly invisible. The email copied npm's logo, colors, and branding perfectly, claimed accounts would be locked on September 10, and included a "Update 2FA Now" button linking to a credential-harvesting page.
[email protected]. Footer: "Sent with ♥ by npm." Indistinguishable from the real thing on a mobile screen.The developer entered his credentials and live TOTP code. The attacker relayed them in real time — before the 30-second OTP expired — and took over the account. 27 packages were poisoned with a crypto wallet drainer that silently redirected Bitcoin, Ethereum, and Solana transactions to attacker-controlled addresses.
Key lesson: Time-based one-time passwords can be stolen in real time. A FIDO security key (fingerprint, YubiKey) cannot — it is bound to the exact website domain and will refuse to authenticate on a lookalike.
SANDWORM_MODE — When the Worm Learned to Whisper to AI
The hidden instructions injected into each AI tool's description. Every innocuously named tool — index_project, lint_check, scan_dependencies — secretly told the AI to read and forward credentials.
The full attack chain: a single npm install leads to credential theft, AI tool hijacking, self-propagation, and a deadman switch that wipes the machine if the stolen token is revoked.
TanStack — 84 Packages, Valid Security Certificates, 6 Minutes
The most technically sophisticated attack in npm's history. By exploiting a misconfiguration in TanStack's automated GitHub Actions release workflow, attackers hijacked the legitimate publishing pipeline itself — stealing a short-lived OIDC authentication token directly from server memory. Because the malicious packages were published by TanStack's own official pipeline, they carried valid cryptographic provenance attestations — the security certificates that are supposed to prove a package is trustworthy. For the first time, those certificates lied.
The full attack sequence. Packages went live with valid security attestations despite the workflow ultimately failing. Detected by an external researcher 20 minutes after the first publish.
bun.exe making an outbound connection to git-tanstack.com:443 — the attacker's C2 server — during a routine npm install.
TeamPCP Open-Sources the Worm — and Announces a Competition
One day after TanStack, the attackers published the complete worm source code on GitHub under the MIT license with the message: "Shai-Hulud: Open Sourcing The Carnage. Is it vibe coded? Yes. Does it work? Let results speak. Change keys and C2 as needed. Love — TeamPCP." They simultaneously announced a $1,000 Monero prize on a hacker forum for whoever caused the most damage with it. A copycat attack appeared within 5 days. GitHub removed the repo within hours — but not before 26 forks appeared.
The actual GitHub page. MIT licensed. 26 forks before takedown. "A Gift From TeamPCP."
What GitHub Just Changed
Every attack above shared one root cause: a single stolen credential was enough to immediately publish code to millions of users. GitHub has now broken that into two separate, mandatory steps.
Step 1 — Stage it
A developer (or their automated pipeline) uploads a new package version to a waiting area. It is not live. Nobody can install it yet.
Step 2 — A human approves it
A real maintainer, on their own device, with a live second-factor verification, reviews and approves the release. Only then does it go live.
A stolen password, a hijacked pipeline, or a phished login code is no longer enough on its own. An attacker would also need to physically possess the developer's security key at the moment of approval — which is far harder.
GitHub also introduced controls that let teams lock down where their projects are allowed to download code from — so malicious links buried in dependencies can no longer silently pull code from attacker-controlled servers.
What To Do Right Now
Two audiences, two checklists.
If you maintain an npm package:
Switch on staged publishing
Available now for all npm packages. Requires npm CLI version 11.15.0 or newer and Node.js 22.14.0 or higher. Your CI pipeline stages the release — you approve it from your device.
Replace your TOTP authenticator with a security key
The chalk/debug attack proved TOTP codes can be stolen in real time. npm has deprecated TOTP and now requires FIDO security keys — a hardware key (YubiKey) or biometric (Touch ID, Windows Hello). FIDO keys are bound to the exact domain and cannot be relayed to a lookalike site.
Never click security emails — go directly to npmjs.com
npm will never ask you to update 2FA by clicking a link in an email. If you receive such an email, open a new browser tab and go to npmjs.com directly.
If you use npm packages in your projects:
Pin your dependency versions
Use exact version numbers in package.json rather than ranges. When a new malicious version is published, pinned projects are not automatically updated to it.
Run npm audit regularly
The npm audit command checks your dependencies against the npm security advisory database. Run it in CI and on a regular schedule.
Watch for suspicious install-time activity
Legitimate packages rarely need to run code or make network connections during npm install. Tools like StepSecurity Harden-Runner caught the TanStack attack in real time by monitoring outbound connections during CI installs.
The Bottom Line
Seven years. Fourteen major incidents. Attacks went from "trick a tired maintainer once" to "self-spreading worms that talk to AI assistants, defeat security certificates, and open-source themselves on GitHub with a prize competition attached."
GitHub's new staged publishing requirement is the first structural fix that addresses the root cause: a single stolen credential is no longer enough to ship code to the world.
Enable staged publishing. Switch to a FIDO key. Never click 2FA emails. Do it today.
Official References
- GitHub Changelog — Staged Publishing and New Install-Time Controls for npm (May 22, 2026)
- GitHub Blog — Our Plan for a More Secure npm Supply Chain
- npm Docs — Staged Publishing
- npm Docs — Trusted Publishers
- npm Docs — About Two-Factor Authentication
- NIST NVD — CVE-2026-45321 (CVSS 9.6)
- GitHub Advisory Database — GHSA-g7cv-rxg3-hmpx
Vulnerability Assessment
Deep technical analysis of vulnerabilities affecting your infrastructure — beyond CVSS scores to real-world exploitability and impact.
Attack Surface Intelligence
Passive mapping of your external presence — every exposed service, endpoint, and piece of infrastructure visible to the public internet.
Threat Hunting
Proactive detection of compromise indicators, APT activity, and post-exploitation artifacts across your email and identity infrastructure.
Dark Web Monitoring
Continuous surveillance of stolen credential markets, threat actor forums, and data leak channels. Know when you're being targeted before it becomes an incident.