Back to all posts
Critical Supply Chain

Mini Shai Hulud Returns:
AntV npm Ecosystem Attack

Attackers stole an npm maintainer token and pushed malicious versions into 42 packages across the AntV namespace plus several widely used dependencies. The payload exfiltrates GitHub, npm, GCP, AWS, and Vault credentials, mints OIDC tokens to forge Sigstore provenance, and persists in .claude/settings.json and .vscode/tasks.json.

CyberXYZ Security Team Threat Intelligence
9 min read
If you use AntV, jest canvas mock, size sensor, timeago.js, jest date mock, or echarts for react in CI or on developer machines, treat this as active.

Audit installs since 2026-05-19 01:39 UTC for any version published in the attack window. Rotate GitHub PATs, npm tokens, AWS keys, GCP service account keys, and Vault tokens for any CI runner or developer workstation that touched an affected version.

What happened

Between 01:39 and 02:06 UTC on May 19, 2026, a single stolen npm publish token was used to push malicious versions of 42 packages spanning the AntV organization and several unrelated but widely used npm libraries. A same day update expanded the confirmed list to 633 affected versions across more than 100 package names. The attack reuses the technique cluster the security community first labelled Mini Shai Hulud in earlier 2026 incidents. The payload is purpose built for credential theft on developer and CI environments.

Timeline

How the attack works

Two execution paths run in parallel. The first set, the trigger packages, declares an optionalDependencies entry that resolves to a raw GitHub commit reference such as github:antvis/G2#1916faa365f2788b6e193514872d51a242876569. npm resolves the reference, downloads the commit, and runs its prepare script during install. The commit is not part of any official branch and exists only to deliver the payload.

The second set, the propagated packages, embeds the payload directly. Each affected version ships an obfuscated index.js of roughly 500 KB at the package root, wired with "preinstall":"bun run index.js" so the payload runs under the bun runtime before any user script gets a chance to inspect the install. The obfuscation routine resolves through globalThis.fc2edea72. The payload includes a __DAEMONIZED reentrancy guard so it does not respawn itself on repeat installs in the same environment.

Socket Threat Research counted 639 malicious versions across 323 unique packages in the May 19 wave alone, with the full campaign spanning 1,055 versions across 502 packages when combined with prior Mini Shai Hulud incidents. The package list extends beyond the AntV namespace into @lint-md/*, @openclaw-cn/*, @starmind/*, and several unrelated test ecosystem libraries.

What it steals

The collector targets credentials commonly present on developer workstations and CI runners. It enumerates the process environment, attempts the AWS IMDSv2 metadata endpoint at 169.254.169.254 and the ECS task metadata endpoint at 169.254.170.2, and parses local config files. The full target list, cross referenced from Endor Labs and Socket disclosures, includes the following.

Collected credentials are AES 256 GCM encrypted with an RSA OAEP wrapped session key, gzipped, and sent to two parallel exfiltration channels. The primary endpoint is t.m-kosche.com at https://t.m-kosche.com:443/api/public/otel/v1/traces, masquerading as OpenTelemetry trace data on port 443. A secondary channel posts to filev2.getsession.org/file/, a Session P2P endpoint over TCP/443. Stolen credentials are also published into attacker controlled GitHub repositories under a results/results-<timestamp>-<counter>.json path, with repository names drawn from Dune themed patterns like sayyadina-stillsuit-852 and atreides-ornithopter-112, and a reversed marker string niagA oG eW ereH :duluH-iahS embedded in the repo description.

Sigstore provenance forgery

The most novel element is the abuse of the GitHub Actions OIDC token. With ACTIONS_ID_TOKEN_REQUEST_TOKEN in hand on a CI runner, the payload mints a fresh OIDC identity token and uses it to sign payloads through the public Sigstore Fulcio instance. The result is a package that appears to carry a valid Sigstore badge while having no genuine provenance link to the project repository. This breaks an assumption that some downstream verifiers rely on, namely that the presence of a Sigstore signature implies a verified build path.

Persistence on developer machines

Beyond exfiltration, the payload writes hooks into two configuration files commonly tolerated on developer machines.

Indicators of compromise

TypeIndicatorContext
npm package jest-canvas-mock@2.5.3 First trigger package, phantom commit dropper
npm package size-sensor@1.0.4 Second trigger package, phantom commit dropper
npm package @antv/l7-core@2.26.10 Embedded payload, preinstall hook
npm package @antv/setup Dropper alias injected via optionalDependencies
npm packages @antv/g2, @antv/g, @antv/x6, @antv/l7, @antv/s2, @antv/f2, @antv/g2plot, @antv/graphin, @antv/data-set Additional AntV namespace packages confirmed affected
Primary C2 t.m-kosche.com Exfiltration endpoint masquerading as OpenTelemetry
Exfil URL https://t.m-kosche.com:443/api/public/otel/v1/traces Primary credential post target, port 443
Secondary C2 filev2.getsession.org/file/ Session P2P network over TCP/443
git author email claude@users.noreply.github.com Spoofed commit author on phantom drops
git commit sha 1916faa365f2788b6e193514872d51a242876569 Phantom commit on antvis/G2
git commit sha 7cb42f57561c321ecb09b4552802ae0ac55b3a7a Phantom commit on antvis/G2
SHA 256 a68dd1e6a6e35ec3771e1f94fe796f55dfe65a2b94560516ff4ac189390dfa1c index.js in @antv/l7-core malicious release
preinstall string "preinstall":"bun run index.js" Exact lifecycle hook used by propagated packages
obfuscation marker globalThis.fc2edea72 Symbol used to resolve the obfuscated payload entry
repo path pattern results/results-<timestamp>-<counter>.json Stolen credential write path inside attacker repos
repo description marker niagA oG eW ereH :duluH-iahS Reversed campaign signature (decodes to "Shai-Hulud: Here We Go Again")
repo name pattern sayyadina-*, atreides-*, harkonnen-* Dune themed attacker controlled GitHub repos
How to check your fleet

Audit your lockfiles and CI logs for any install of the listed packages with publish times after 2026-05-19 01:39 UTC. Inspect ~/.claude/settings.json and ~/.vscode/tasks.json on developer machines for unexpected hooks. On any CI runner that ran npm install during the attack window, treat the runner as compromised and rotate every secret it had access to.

MITRE ATT&CK mapping

What CyberXYZ shipped in response

Within hours of the Endor Labs disclosure we shipped four changes across the detection engine.

Customers running the CyberXYZ proxy are now protected against future install attempts of any affected version. Any matching request is blocked at the edge before the install hook gets to execute.

Recommended actions this week

Immediate. Block the listed packages at your registry proxy or private mirror. If you do not have a proxy in front of npm in CI, add one. Audit lockfiles for any install since 01:39 UTC on May 19. Treat any CI runner that touched an affected version as compromised and rotate every secret it had access to.

Short term. Disable preinstall, postinstall, and prepare hooks on CI runners using npm install --ignore-scripts. For packages that legitimately require install hooks, allow list them explicitly. Inspect ~/.claude/settings.json and ~/.vscode/tasks.json across the fleet for unauthorized hooks.

Long term. Add npm publish token rotation to your maintainer offboarding and incident playbooks. Require Sigstore provenance attestation to include a verified Git commit reference, not only a signature. Treat the presence of a Sigstore badge as a useful signal, not a sufficient one.

Maintainer token compromise is the fastest and most aggressive supply chain attack pattern of 2026. The publish takes minutes. The downstream cleanup takes weeks. Pre publish controls and registry side blocking are the only layers that meet this on its actual timeline. Everything that runs after install is already a response, not a prevention.

The CyberXYZ Supply Chain Firewall enforces malicious package blocks at the proxy layer, so a confirmed indicator becomes an organization wide protection the moment it lands in our corpus. If you want to see how your fleet would have responded to this attack, the team is happy to walk through the detection chain with you.


References

  1. Endor Labs, Mini Shai Hulud Returns: 42 Malicious npm Packages and Fake Sigstore Badges in AntV Ecosystem Attack
  2. Socket Threat Research, AntV Packages Compromised: Mini Shai Hulud Returns at Scale
  3. MITRE ATT&CK, T1195.002 Compromise Software Supply Chain
  4. MITRE ATT&CK, T1556 Modify Authentication Process
  5. Sigstore, OIDC signing with Sigstore
  6. npm documentation, npm scripts and lifecycle hooks
👋

Let's Talk

Want to learn how CyberXYZ protects your supply chain? We'd love to hear from you.