On May 19, 2026, an attacker who had compromised the npm account of an AntV maintainer published malicious versions of the ecosystem's data-visualization packages in a single automated burst. Microsoft's analysis counted 637 malicious versions across 317 packages, published in roughly 22 minutes. Affected names include size-sensor, echarts-for-react, timeago.js, and hundreds of @antv scoped packages, with monthly downloads in the millions.
The campaign got the name Mini Shai-Hulud for its resemblance to the earlier self-replicating worm wave. The response was also large: per StepSecurity's reporting, GitHub removed about 640 packages and invalidated more than 61,000 npm granular access tokens.
The payload aimed at CI, not laptops
The interesting part is the target. The ~499 KB obfuscated payload runs at npm install time and is built for GitHub Actions environments: it harvests GitHub, AWS, HashiCorp Vault, npm, Kubernetes and 1Password credentials, and it scrapes the GitHub Actions runner's process memory, where OIDC tokens and just-minted secrets live in cleartext.
That last technique deserves attention. A runner's process memory is outside the threat model of most secret-management advice. Rotating a token does not help if the malware reads the new one out of /proc while the job runs.
What detection looked like on our side
Two layers, both shipped before this incident:
Known-bad matching. The compromised versions flowed into the advisory data Aguara matches against. aguara check . reads the lockfile of a freshly cloned project, so the compromised tuple gets caught before install. v0.16.0, released the week before, embedded the full OSV-derived snapshot in the binary and added aguara update and --fresh for signed refreshes when an incident is moving fast:
$ aguara check . --fresh
CRITICAL pnpm-lock.yaml
known-compromised-package: @antv/g2@5.6.8
npm · SOCKET-2026-05-19-mini-shai-hulud-antv
Behavioral rules for the techniques. The runner memory pivot was already a detection: JS_PROC_MEM_OIDC_001 flags JavaScript that reaches into process memory on a CI runner, and JS_CI_SECRET_HARVEST_001 flags the secret-sweep pattern in install-time code. Technique rules age better than IOC lists: the next campaign will use new package names and the same tricks.
The uncomfortable math of 22 minutes
From first malicious publish to full burst took under half an hour. No human review loop reacts in that window. The defenses that work at that speed are structural: lockfile checks against advisory data before install, a release-age window so brand-new versions wait before CI consumes them, and build-script approval so install-time code does not execute silently. pnpm v11 ships the latter two as defaults; checking the first is what aguara check exists for.
Further reading: Socket's advisory and Snyk's writeup.
Your CI installs packages faster than you read advisories
Gate it: aguara audit . --ci returns exit 1 on a known-compromised package, before install scripts run.