Infected NPM Packages: Shai-Hulud Swallowed the Supply Chain
The Shai-Hulud worm turned 2026 into the year of infected npm packages — see how the attack works, who was hit, and how to harden your pipeline.
by Cleverson

Infected npm packages stopped being an occasional scare in 2026 and became the permanent backdrop of JavaScript development. In less than twelve months, the self-propagating worm Shai-Hulud hijacked maintainer accounts, planted backdoors in over 796 libraries, and hit projects like TanStack, AntV, Axios, NX, and even OpenAI's internal infrastructure. If your package.json was touched in this cycle, this post shows what changed, how to detect contamination, and how to harden your pipeline before the next CVE.
TL;DR — what you need to know about infected npm packages in 2026
- Shai-Hulud is a self-propagating worm: it steals npm credentials from the victim's machine or CI and publishes malicious versions of everything that maintainer controls, without needing a C2 server.
- In 2026 there have already been four major waves: TanStack (11 May), AntV (300+ versions, 19 May), Axios (March), and the CanisterSprawl worm, which uses AI to vary payloads.
- The main targets are cloud tokens (AWS/GCP), macOS signing keys, CI/CD secrets, and AI API keys (OpenAI, Anthropic, Mistral).
- The defence is not "blindly update everything" — it's freeze versions, audit lifecycle scripts, and disable arbitrary
postinstall.- Brazilian teams running AI in production are on the front line because their CI runners execute
npm installwith privileges and live tokens in the environment.
What happened with infected npm packages in 2026
The timeline of infected npm packages over the last six months reads like an ICU chart:
- November 2025 — the original Shai-Hulud emerges, the first npm worm to self-replicate by reading its own payload source code.
- 24 November 2025 — Shai-Hulud 2.0 accelerates propagation and adds execution in
preinstall, evading audits that only look at published code. - 31 March 2026 — version
1.14.1of Axios is published at 00:21 UTC with a phantom dependency calledplain-crypto-js, implanting a remote access trojan before any code review. - 11 May 2026 — in a six-minute window (19:20–19:26 UTC) 84 malicious versions in 42 TanStack packages are published, including
@tanstack/react-router(12M weekly downloads). OpenAI confirms two internal devices compromised and forces rotation of macOS signing certificates for ChatGPT, Codex, and Atlas until 12 June. - 19 May 2026 — a 22-minute automated burst publishes over 300 malicious versions in 323 AntV packages, expanding the blast radius to the Chinese data visualisation ecosystem.
The cumulative total: 796 unique packages compromised, ~20 million infected weekly downloads, over 25,000 malicious repositories on GitHub, and confirmation that infected npm packages are no longer an incident — they are the landscape.
Anatomy of the Shai-Hulud worm
This family of infected npm packages is not spam — it's well-designed malicious software architecture. The cycle follows four reproducible stages.
Stage 1 — maintainer account compromise
The entry point is almost always the same: targeted phishing, an npm token leaked in a public log, or an OIDC key stolen from a GitHub Actions runner. In the TanStack case, the attack hijacked the legitimate release pipeline with valid OIDC identity, which made the package ship with signed SLSA provenance — the first time this was documented.
Stage 2 — backdoor in all of the victim's packages
With the token in hand, the worm does not publish to one package — it publishes to all. The script enumerates what that maintainer controls via npm whoami + npm access ls-packages and injects the payload into up to 100 packages per execution, with a minor version bump to avoid immediate suspicion.
Stage 3 — exfiltration via public GitHub
The Shai-Hulud 2.0 payload uses public GitHub repositories as a reverse C2 channel. It creates a repo in the victim's account with a random name, dumps collected secrets (environment variables, .env files, ~/.aws/credentials, ~/.npmrc, ~/.docker/config.json), and attackers simply scrape these repos with search queries.
Stage 4 — self-propagation
Final stage: the worm reuses npm tokens found on the victim's system to publish backdoored versions to other packages that developer has publish access to — often as a collaborator on company libraries. This is what turned the campaign into a pandemic: each victim becomes a vector.
The incidents that marked 2026 — comparison table
| Date | Package / family | Impact | Initial vector |
|---|---|---|---|
| 24/11/2025 | Shai-Hulud 2.0 (generic) | 796 packages, 20M downloads/week | Leaked npm token |
| 31/03/2026 | [email protected] |
RAT in millions of Node.js apps | Hijacked maintainer account |
| 11/05/2026 | TanStack (42 packages) | 12M+ downloads/week, OpenAI hit | Release pipeline OIDC |
| 19/05/2026 | AntV (323 packages) | Entire dataviz ecosystem | Maintainer account |
| May/2026 | NX | AWS admin access in <72h | Stolen CI key |
| Ongoing | CanisterSprawl | LLM-orchestrated worm | Phishing + AI automation |
Note the acceleration: from one big worm in November to four waves in six months. The cost of running such campaigns has plummeted and the barrier to entry is now lower than running a SaaS.
Why the npm ecosystem is so vulnerable
npm carries about 3 million packages and exceeds 17 billion downloads per week, and this scale is exactly what makes infected npm packages so lethal. Five structural reasons that nobody has solved yet:
- Arbitrary lifecycle scripts — any
package.jsoncan runpostinstall,preinstall, orpreparewith full permissions in the developer's environment. It's a feature, not a bug, and has existed since 2012. - Deep transitive dependencies —
axioslooks like a single library, but pulls in about 50 indirect deps. You trust who you trust who you trust. - Optional signing until recently — only in 2025 did SLSA provenance become standard, and TanStack showed that signed provenance does not prevent the attack if the pipeline is already compromised.
- Long-lived npm tokens — most developers do not rotate the token published in 2019. Without rotation, one leak is enough.
- Culture of "update quickly" — Dependabot opens a PR, someone clicks "merge" without reading the diff, the pipeline pulls the freshly published version
1.14.1, and the RAT is inside in forty minutes.
Who is the target of infected npm packages in 2026
The target has changed. In 2023 it was a crypto-bro with a private key in .env. In 2026 the menu is more appetising:
- Brazilian fintechs and exchanges — hot wallet keys are worth the entire attack.
- Teams running AI in production — OpenAI and Anthropic keys are resold on black-hat markets for tens of thousands of dollars each.
- CI pipelines with OIDC for AWS/GCP — escalation to full infrastructure in less than 72 hours, as shown by the NX case.
- Companies with macOS pipelines — signing keys allow distributing malware as if it were your legitimate app, as attempted against OpenAI.
- Brazilian B2B SaaS teams — soft targets, often have a global
.npmrcon the senior dev's Mac with publish permission on corporate libraries.
If your stack runs Node + AI + Cloud, you are in the funnel. It's not paranoia, it's the Google Cloud Threat Horizons H1 2026 report{target="_blank"} pointing this out in black and white.
How to detect if you installed an infected npm package
You can't fully outsource this — but you can process it very quickly. A checklist we apply here at Agathas Web on all custom Moodle apps and on Voyia's infrastructure:
- List recently updated packages in the last 72h:
npm ls --depth=0 --json | jq '.dependencies | to_entries[] | {name: .key, version: .value.version}'. - Cross-reference with public lists of compromised packages — Socket, Snyk Vulnerability DB, OSV-Scanner, and StepSecurity's feed publish IOCs in near real-time.
- Look for suspicious scripts in the installed
package.json:find node_modules -name package.json -exec grep -l "postinstall\|preinstall" {} \;and read each one. - Check your own GitHub for repositories created without your knowledge — Shai-Hulud 2.0 deposits secrets in public repos with random names on your account.
- Audit
~/.npmrcand project.npmrc— any token without2FA enforceis a target. - Review the last 30
npm installruns in CI — if any appeared at an unusual time (3 AM, weekend), treat it as suspicious.
If you find any indicator, revoke all tokens (npm, GitHub, AWS, OpenAI, Anthropic) before trying to clean up. The average active exploitation window today is 48 hours.
How to protect your project in practice
Real defence against infected npm packages is not a feature, it's continuous hygiene. What effectively reduces the surface:
npm ciinstead ofnpm installin CI — installs exactly thepackage-lock.json, without resolving new versions.- Lockfile committed and reviewed in every PR. Changed size for no reason? Audit the diff.
npm config set ignore-scripts truein the CI environment and on developer machines. Breaks two or three legitimate packages, but neutralises 90% of worms.- Short-lived npm tokens (90 days) and mandatory 2FA for
publish. - Private mirror with Verdaccio, Artifactory, or GitHub Packages — you decide when a version enters the inventory.
- Verified SLSA provenance on install (
npm install --audit-signatures) — not a silver bullet, but filters out less sophisticated attacks. - Dependabot with mandatory human review — no more auto-merge on libraries with over 1M downloads.
- Continuous scanning with Socket, Snyk, or OSV-Scanner in CI, failing the build on a newly published critical CVE.
- Quarterly rotation of npm tokens, GitHub Actions, AWS access keys.
No single item is magic. Combined, they reduce the blast radius from "total chaos" to "a scare resolved before coffee".
What changes when AI writes your package.json
Generative AI has created a new vector that nobody saw coming: amplified typosquatting. Copilot, Cursor, and Claude sometimes suggest package names that do not exist — called hallucinated packages — and attackers register those names on npm to harvest the npm install from anyone who accepts the suggestion without checking.
Worse: the CanisterSprawl observed in 2026 uses LLMs to generate automated variations of payloads, changing hashes, exfiltration order, and function names to evade signature-based detectors. It's a worm that rewrites itself.
The countermeasure is not to abandon AI — it's to establish that every dependency suggested by AI goes through manual verification before becoming an npm install. Check the download count, package age, version history, and whether the name exactly matches the official one.
Next steps — dependency governance
Stopping treating infected npm packages as an accident requires setting up a process. The four minimum items:
- Inventory and SBOM — generate a Software Bill of Materials per release with
cyclonedx-npmorsyft. Without an SBOM, you don't know what you have; without knowing what you have, you can't defend. - Approval policy for new deps — any addition to
dependenciesneeds a human reviewer and justification in the PR. An internal standard dependency is cheaper than a CVE. - Limit devDeps — devDeps run in CI with the same privileges as production. Treat them with the same rigour.
- Monitoring and incident playbook — who revokes? Who communicates with clients? Who rotates? Decide before the incident, not during.
This is the same discipline we apply in critical projects like the Official WhatsApp Business API, where a poisoned dependency means leaking customer conversations — you can't outsource this governance to npm install.
Conclusion — infected npm packages are no longer the exception
The big change in 2026 is not technical, it's cultural. Infected npm packages have gone from "regrettable rarity" to "expected baseline scenario". Those who continue to treat npm install as a trusted operation will be caught — it's not if, it's when.
The move I recommend: shift your mental model from "I'll update when I can" to "every new version is untrusted code until proven otherwise". Frozen lockfile, disabled scripts, private mirror, token rotation, CI scanning. In parallel, build an incident playbook with timelines in minutes, not days.
Here at Agathas Web we apply this model in all custom Moodle projects, Voyia (WhatsApp customer service), and AI integrations. The cost is a small ceremony per month; the benefit is not waking up to discover that the client is leaking secrets through the postinstall of a hijacked transitive dependency at three in the morning.
If you don't know where to start auditing your own package.json, that's exactly the request to open as an internal ticket in your team this week — before the next Shai-Hulud.
Related posts

Azure Linux 4: Microsoft Launches Fedora-Based Distro
Microsoft has swapped CBL-Mariner for Fedora as the upstream for Azure Linux 4 and expanded its focus to Azure VMs. What this means in practice.

GitHub Breached: VS Code Extension Leaked 3,800 Repositories
The GitHub breach in May 2026 shows how a single poisoned VS Code extension can bring down fortresses. See the attack and how to protect your team.

Nintendo Switch 2: The NVIDIA AI Paradox in the Console
Nintendo Switch 2 sold 10 million in 7 months, uses NVIDIA DLSS and challenges the industry with its stance against generative AI.