Dateline: May 22, 2026
A Single Account, 637 Malicious Versions, and a Worm That Won’t Stop
A self-replicating worm tore through the npm ecosystem on May 19, hijacking one maintainer account and using it to publish 637 malicious package versions across 317 popular libraries in a 22-minute burst. By the time defenders noticed, the payload had already started exfiltrating GitHub tokens, AWS keys, and Kubernetes secrets from developer machines and CI/CD runners worldwide.
The npm registry responded by invalidating granular access tokens with write permissions across affected accounts, breaking automated publishing workflows for thousands of teams overnight. It’s the latest wave of the Mini Shai-Hulud campaign, and at this point it’s clear the attackers aren’t slowing down.
What Happened?
The breach traces back to a single npm maintainer account, atool, which was compromised sometime before May 19. Once inside, the attackers ran an automated script that pushed malicious versions of every package the account had publishing rights to. The wave swept the entire @antv data-visualization organization, plus widely-used standalone libraries like echarts-for-react (roughly 1.1 million weekly downloads), timeago.js, size-sensor, and canvas-nest.js.
The malicious payload, a roughly 499KB obfuscated JavaScript file, runs silently during npm install through a preinstall hook. It uses bun run instead of node to sidestep script-scanning tools that key on Node.js invocations, then targets credentials across GitHub, AWS, HashiCorp Vault, npm, Kubernetes, and 1Password. On CI runners, it scrapes secrets directly from process memory.
This wasn’t an isolated incident. It’s the same TeamPCP group behind the May 11 attack that compromised TanStack, Mistral AI, UiPath, and over 160 other packages a week earlier. That earlier wave used a chained GitHub Actions exploit to extract OIDC tokens from runner memory — the attackers never even needed npm credentials.

Mini Shai-Hulud is functioning as a true worm: once it harvests a maintainer’s tokens, it automatically clones their other repositories, injects itself, increments versions, and republishes. The infection curve is exponential.
The blast radius is enormous because most affected packages are transitive dependencies. You may have been running this malware without ever directly installing the compromised library.
The Response
Within hours of detection, npm’s security team invalidated granular access tokens with write permissions for affected accounts and worked with GitHub Security to map the full scope. The token reset hit every CI/CD pipeline using those credentials, and Monday-morning deployments collapsed across thousands of teams as builds started failing with authentication errors.
But the token reset is treating a symptom, not the disease. The underlying problem is structural: modern JavaScript projects pull in hundreds of transitive dependencies, each one a potential entry point.
A single compromised maintainer account can ship malware into millions of applications before anyone notices. npm and GitHub are racing to add tighter publishing controls (phishing-resistant MFA, mandatory provenance attestations, lifecycle script restrictions) but adoption across the ecosystem will take months.
Defending Against Mini Shai-Hulud: What to Check and What to Fix
The token reset is one piece of a much larger response effort. If your team uses npm anywhere in your stack, treat the next few hours as an active incident response, not a routine token rotation.

Then rotate everything in scope
If any of those indicators turn up, the credentials touching that environment are no longer trustworthy. The payload targets cloud and infrastructure credentials including AWS credentials, GitHub tokens, GitHub Actions OIDC tokens, HashiCorp Vault tokens, and Kubernetes secrets.
It also targets developer machine files such as SSH keys, package registry tokens, .env files, password managers, shell history, and Claude Code configuration. Rotate all of them, not just npm tokens. A clean scan doesn’t prove a clean environment, it only proves this IOC set didn’t match.
Beyond that, pin dependencies to verified versions in your lockfiles, disable shared caching in CI temporarily, and restrict preinstall/postinstall lifecycle scripts in your build pipelines.
Building the Muscle to Handle the Next One
Manually grepping for payload filenames and chasing down every stale token across every repository is realistic for one incident. It isn’t realistic when supply chain compromises keep hitting on a weekly cadence, which is the cadence we’re now seeing. Most teams need automation working continuously in the background.
That’s where an AppSec teammate built into the development pipeline starts paying off. A few specific capabilities map directly to the Mini Shai-Hulud playbook:
- Continuous software composition analysis flags KEV-listed and known-malicious packages the moment they appear in a build, so the next compromised npm release gets caught before it reaches production.
- Pre-commit secret scanning catches hardcoded tokens in .env files, config files, and source code, then triggers rotation automatically. The credentials that get stolen in attacks like this often shouldn’t have been in code in the first place.
- Credential rotation as policy, not a calendar reminder. Aging tokens get flagged, owners get notified, and rotation happens without a Jira ticket sitting open for three months.
- Blast radius mapping. When the next incident hits, you can see which builds, services, and pipelines depend on the affected packages or tokens instead of finding out at 2 a.m. when production deploys start failing.