Mini Shai-Hulud npm Attack: AntV Ecosystem Compromise (May 2026)
In the early hours of May 19, 2026, the npm maintainer account atool was compromised. Over the next 22 minutes, the attacker pushed malicious versions of 300+ packages spanning Alibaba’s AntV data visualization suite (@antv/g2, @antv/g6, @antv/x6, @antv/l7, and over 100 others), as well as widely used standalone packages such as echarts-for-react, timeago.js, size-sensor, and canvas-nest.js. Multiple supply chain security researchers have classified the campaign as the latest wave of Mini Shai-Hulud, the same malware family behind recent compromises of SAP’s Cloud Application Programming Model libraries, TanStack, and intercom-client.
Every malicious version carries a preinstall hook that runs a 498KB obfuscated Bun script the moment npm install executes. Most versions also inject an optionalDependencies entry pointing to an orphan commit in the legitimate antvis/G2 GitHub repo, delivering a second copy of the payload through a trusted-looking dependency path that evades scanners that only inspect scripts fields in published tarballs.
What the malware does
When a developer or CI system installs an affected version, the preinstall hook runs bun run index.js before any other install logic. If Bun isn’t already present, the malware silently installs it. The payload then executes four operations in sequence:
Credential harvesting. The stealer sweeps more than 20 credential types: the full AWS chain (env vars, config files, EC2 IMDS, ECS container metadata, Secrets Manager), Google Cloud, Microsoft Azure, GitHub PATs, npm tokens, SSH keys, Kubernetes service account tokens, HashiCorp Vault, Stripe keys, database connection strings, and local password manager vaults (1Password, Bitwarden, pass, gopass).
Cloud metadata probing. The payload makes outbound requests to
169.254.169.254and169.254.170.2to retrieve cloud instance metadata and attempts to escape a Docker container via the host socket.Encrypted exfiltration. Stolen data is serialized, compressed, RSA-encrypted, and exfiltrated to
t.m-kosche.com:443using OpenTelemetry-style request paths to blend with legitimate traffic.Fallback publish to GitHub. If the C2 channel fails, the malware uses the stolen GitHub token to create a public repository under the victim’s own account and commit the harvested data as JSON. The repos carry the description “niagA oG eW ereH :duluH-iahS” — “Shai-Hulud: Here We Go Again” reversed.
A subset of compromised packages, including echarts-for-react, also forge SLSA provenance attestations using Sigstore when running in a CI environment with an OIDC token available. That means, in some environments, the malicious release is signed with a legitimate Sigstore certificate and is indistinguishable from a real release based solely on signature checks.
Scale and blast radius
The atool account maintained 547 npm packages. The attacker hit 314 of them with 637 malicious versions in two automated waves between 01:39 and 02:18 UTC. The broader Mini Shai-Hulud campaign now spans over 1,000 malicious versions across more than 500 unique packages, hitting npm, PyPI, and Composer.
The compromised packages collectively represent approximately 16 million weekly downloads. Individual package exposure is significant:
size-sensor— roughly 1M weekly downloadsecharts-for-react— 1.1M weekly downloads, a near-universal React wrapper for Apache EChartstimeago.js— 1.5M weekly downloads@antv/scale— roughly 500k weekly downloadsHundreds of other
@antvscoped packages, plus packages under@lint-md,@openclaw-cn, and@starmind
The attacker did not move the latest dist-tag on most packages. That provides no protection. npm’s semver resolution picks the highest version matching a range regardless of the latest tag, so any project with "echarts-for-react": "^3.0.6" in its package.json will resolve to a malicious version on the next clean install.
Indicators of compromise
If your package-lock.json or yarn.lock references any package maintained by the atool account with a resolved version published between 01:39 and 02:18 UTC on May 19, 2026, treat the environment as fully compromised.
Network indicators
C2 domain:
t.m-kosche.com:443Suspicious outbound:
169.254.169.254or169.254.170.2(cloud metadata endpoints) from non-cloud contextsGitHub API calls with
python-requests/2.31.0User-Agent not originating from actual Python processes
Package-level indicators
Any atool-maintained package with a
preinstallscript ofbun run index.jsImposter
optionalDependenciesentry:"@antv/setup": "github:antvis/G2#<sha>"(known commits:1916faa365f2788b6e193514872d51a242876569,7cb42f57561c321ecb09b4552802ae0ac55b3a7a)Public GitHub repos created under your account with description “niagA oG eW ereH :duluH-iahS”
File artifacts
A root-level
index.jsapproximately 498KB in size, single-line, heavily obfuscated Bun bundleA
gh-token-monitor.shdaemon polling tokens every 60 seconds
Immediate steps if you’re affected
Audit lockfiles immediately. Audit your lockfiles and dependency manifests for any packages from the atool-maintained package set. Multiple supply chain security researchers have published public advisories with the full list.
Treat affected environments as fully compromised. The RSA-encrypted exfiltration means you cannot recover what was taken from network logs. Assume every credential reachable from the install context has been exfiltrated.
Rotate everything. AWS, Azure, GCP keys; SSH keys; kubeconfig; GitHub PATs; npm tokens; Vault tokens; Stripe keys; database credentials; and any local password manager vaults that were unlocked on the affected machine.
Audit your GitHub account. Check for unexpected public repositories created on your account, especially with reversed-string descriptions. Delete them only after capturing the contents for forensics.
Block the C2 at egress. Block
t.m-kosche.comat your network perimeter for CI runners and developer machines.Review CI/CD logs. Look for unexpected repository creation activity, OIDC token usage, and Sigstore signing operations that don’t correspond to legitimate releases.
Why Chainguard customers were protected
Chainguard customers were not affected by this attack. The protection comes from a single architectural choice we’ve made consistently across the JavaScript Libraries catalog: we don’t build libraries that use install-time scripts.
Mini Shai-Hulud, like nearly every recent npm credential stealer (Shai-Hulud, SAP CAP, TanStack, intercom-client, CanisterWorm), relies on preinstall, postinstall, or prepare hooks to execute its payload. These hooks fire automatically during npm install, before any application code runs, and before any human reviews the dependency. Install-time scripts are the dominant malware delivery vector in the npm ecosystem, and they’re also rarely necessary: a curated catalog can strip or refuse to build packages that require them, without breaking real applications.
Chainguard Libraries for JavaScript does exactly that. Packages that depend on install-time scripts don’t get built into our catalog. The malicious AntV versions could not execute in a build pipeline that consumes Chainguard Libraries because the preinstall hook would never have fired — we wouldn’t have built the version in the first place.
For customers using Chainguard Repository's upstream npm fallback, the default 7-day cooldown on newly published versions would have blocked the malicious AntV packages from being served during the attack window — the entire malicious publish window was 39 minutes. Passthrough packages are not exempt from the threat: if a malicious package reaches a developer or CI environment through a passthrough path, the preinstall hook fires just as it would from a direct npm install. The 7-day cooldown is an aggressive, default-on control specifically designed to prevent newly published versions — the window where supply chain attacks are most active — from reaching customers before the broader security community has had time to assess them.
Scanners may have flagged this attack, but only after the packages were already published and potentially installed. The malicious versions were live on the public registry for minutes before any detection appeared, which is enough time for a CI runner to install a poisoned package, exfiltrate credentials, and post the stolen data to a public GitHub repo. The Chainguard approach blocks the attack class entirely, before any version-specific detection is needed.
The bigger picture
This is the third major Mini Shai-Hulud wave in roughly four weeks. SAP’s Cloud Application Programming Model libraries on April 29. TanStack the same day. Now AntV with more than 600 malicious versions published in a single 22-minute burst. The toolkit is mature, the operators operate on a tight cadence, and every wave targets a different ecosystem corner: enterprise SAP infrastructure, modern React state management, and Alibaba’s data visualization stack.
Three things are worth pulling out of this incident specifically:
Sigstore signatures are not a substitute for provenance. This wave forges SLSA attestations using OIDC tokens stolen from compromised CI environments. A signature tells you a CI job signed a package; it does not tell you whether that CI job was running legitimate code. Pre-built malware survives signature verification.
Imposter commits are a real attack surface. The optionalDependencies trick used here is the same class of attack we documented for GitHub Actions: pushing an orphan commit to a legitimate repository’s object store and referencing it by SHA. npm resolves github:org/repo#<sha> without verifying which branch, tag, or even which fork the commit originated from. The commit persists until garbage collection, no PR or branch update appears in the event log, and the legitimate org takes the blame.
Single-account compromises are grossly asymmetric. One phished maintainer account, 547 packages under publish control, ~16M weekly downloads exposed in 22 minutes. The economics of supply chain attacks favor the attacker by orders of magnitude. The defender’s only sustainable answer is to remove the install-time-script attack surface entirely, not to chase individual malicious versions after publication.
If your team is still consuming JavaScript libraries directly from npm with install-time scripts enabled, there is a high probability this campaign will hit you. The question is when, and which credentials are reachable from the install context. Get in touch with our team to learn how Chainguard can protect your software supply chain.
Share this article
Verwandte Artikel
- Sicherheit
Canada's CPCSC and Bill C-8 are coming. Here's what you need to do.
Chris Carty, Enterprise Solutions Engineer
- Sicherheit
Node-ipc compromised: Credential stealer targets package with 500k+ weekly downloads
Quincy Castro, CISO
- Sicherheit
Luck isn't a security control: What happened with mini Shai-Hulud and what you need to do
David Henry, Staff Product Marketing Manager
- Sicherheit
Cyber resiliency in practice: Lessons from recent supply chain attacks
Mike Behrmann, Director, Cyber Resiliency
- Sicherheit
Chainguard artifacts safe from npm supply chain attack targeting SAP developer dependencies with 2.25M+ monthly downloads
Quincy Castro, CISO
- Sicherheit
CMMC Phase 2, explained: Requirements, deadlines, and who’s affected
Philip Brooks, Senior Enterprise Solutions Engineer