Mini Shai-Hulud Strikes Again: 314 npm Packages Compromised
The npm account atool ( [email protected] ) was compromised on May 19, 2026. The attacker published 637 malicious versions across 317 packages in a 22-minute automated burst. Affected packages include size-sensor (4.2M downloads/month), echarts-for-react (3.8M), @antv/scale (2.2M), timeago.js (1.15M), and hundreds of @antv scoped packages. The payload is a 498KB obfuscated Bun script that matches the Mini Shai-Hulud toolkit used in the SAP compromise three weeks earlier: same scanner architecture, same credential regex set, same obfuscation pattern. It harvests credentials across the full AWS chain (env vars, config files, EC2 IMDS, ECS container metadata, Secrets Manager), Kubernetes service account tokens, HashiCorp Vault, GitHub PATs, npm tokens, SSH keys, and more. Stolen data is exfiltrated by committing it as Git objects to public GitHub repositories created under the compromised token, with the User-Agent forged as python-requests/2.31.0 . In CI environments, the payload exchanges GitHub Actions OIDC tokens for npm publish tokens, signs artifacts via Sigstore (Fulcio + Rekor) using the stolen identity, and injects persistence into .github/workflows/codeql.yml . The payload hijacks Claude Code and Codex by injecting SessionStart hooks that re-execute the malware on every AI session, both locally and via commits to accessible GitHub repositories. VS Code gets a tasks.json with "runOn": "folderOpen" for the same effect. A persistent systemd service / macOS LaunchAgent ( kitty-monitor ) installs a GitHub dead-drop C2 backdoor: a Python daemon that polls GitHubโs commit search API hourly for RSA-PSS signed commands in commit messages containing the keyword firedalazer , then downloads and executes arbitrary Python from the signed URL. A separate gh-token-monitor daemon polls stolen GitHub tokens at 60-second intervals. The payload also attempts Docker container escape via the host socket and propagates infection to other local Node.js projects.
The attack uses two execution paths. Each compromised version adds a preinstall hook ( bun run index.js ). 630 of 637 versions also inject an optionalDependencies entry pointing to imposter commits in the antvis/G2 GitHub repository. These are orphan commits with forged authorship, invisible in the repoโs branch history, exploiting GitHubโs fork object sharing to host a second copy of the payload without any write access to the target repository. npmโs github: dependency resolution fetches and executes the content by SHA.
If you are auditing lockfiles or reinstalling on affected machines, Package Manager Guard (pmg) is an open-source install proxy that evaluates packages against threat intelligence before preinstall scripts run. Its dependency cooldown can refuse versions published inside a configurable window, which helps against bursts like the May 19 wave where semver ranges were still resolving to freshly published malicious releases.
The atool npm account maintains 547 packages. The attacker published 637 malicious versions across 314 of those packages in two automated waves, both on May 19, 2026:
Most packages (309) received exactly 2 malicious versions, one per wave. Four packages ( size-sensor , echarts-for-react , jest-canvas-mock , jest-date-mock ) received 3 versions, suggesting they were used for early testing before the bulk publish.
A sample of the highest-impact affected packages: