The Mini Shai-Hulud worm,
and where the firewall stops it.
Between 01:39 and 02:06 UTC on May 19, 2026, a single stolen npm publish token pushed malicious
versions of dozens of packages across the AntV namespace and several widely used test libraries.
Each one ran a credential harvester before any user script. No CVE existed. Here is the timeline,
and where CyberXYZ blocks it. CyberXYZ did not catch this wave early: our npm publish stream was
42 million messages behind and first saw jest-canvas-mock@2.5.3 about 36 hours after
it was published. We blocked it from Endor Labs' disclosure: the packages reached our block list
5 h 51 min after Endor Labs published.
-
01:39 UTC
A stolen publish token goes live
A single compromised npm publish token starts shipping. The first trigger package,
jest-canvas-mock@2.5.3, looks ordinary, but it carries anoptionalDependenciesentry pointing at a raw GitHub commit hash. -
01:39 UTC · what the commit-level signal looks for
A phantom commit drops the payload
The referenced commit (
github:antvis/G2#1916faa…) exists on no branch. npm resolves it, downloads it, and runs itspreparescript on install. A dependency that resolves to a commit on no branch is the pattern CyberXYZ's commit-level signal looks for. -
01:44 UTC
A second trigger lands
size-sensor@1.0.4ships with the same phantom-commit technique. Two unrelated, widely used packages now both carry the dropper. -
01:56 UTC · what the script scan looks for
The namespace is flooded
A burst of 14 packages publishes at once, including
@antv/g6,@antv/scale,timeago.jsandecharts-for-react. Each embeds a roughly 500 KB obfuscatedindex.jswired to"preinstall":"bun run index.js", so it runs before any user script can inspect it. -
on execution (had it run)
What it would have stolen
The payload enumerates the environment, hits the AWS metadata endpoint at
169.254.169.254, and harvests GitHub, AWS, GCP, Kubernetes, Vault and npm credentials, then exfiltrates them tot.m-kosche.comdisguised as OpenTelemetry traces on port 443. -
the novel part
Sigstore provenance forgery
On a CI runner the payload mints a fresh GitHub Actions OIDC token and signs through public Sigstore, producing a package that appears to carry a valid provenance badge with no genuine link to the project. A signature alone is no longer proof.
-
02:22 UTC
The first public disclosure lands
Endor Labs publishes the initial write-up; Socket Threat Research later counts 639 malicious versions across 323 packages in this wave alone.
-
08:57 UTC · after the disclosure
BLOCK, at install time
The named packages were added to CyberXYZ's block list at 08:13 UTC from Endor Labs' disclosure, 5 h 51 min after it was published, and the first real block of
jest-canvas-mock@2.5.3came at 08:57 UTC. From then on, installing a listed version through the proxy returns403, CI gates fail and the editor flags it. -
afterwards
What we changed
We backfilled 28 named packages into the malicious-package corpus, added six indicators (the exfil domain, the spoofed author marker, two phantom commit SHAs and the payload hash), moved 2,233 npm packages with over a million monthly downloads onto 15-minute polling, and restored the npm publish stream, which had fallen 42 million messages behind. The technical write-up has the detail.
What the proxy returned
for the trigger package.
This is the real record from CyberXYZ's install log: one internal test install, blocked at 08:57 UTC on May 19, after Endor Labs' disclosure. The full IOC table (package/version pairs, C2 domains, commit SHAs) is in the technical write-up.
fig. 01 · proxy findings · the real block, an internal test install, 7 h 18 min after the trigger package was published
Blocked install: jest-canvas-mock@2.5.3 on gha/runner · GitHub Actions
A ~500 KB obfuscated index.js is wired to a preinstall hook (bun run index.js) so it executes before any user script.
optionalDependencies resolves to a raw GitHub commit that exists on no branch and only delivers the payload via the prepare hook.
Reads the AWS metadata endpoint 169.254.169.254 and harvests GitHub, AWS, GCP, Vault and npm secrets, exfiltrating to t.m-kosche.com.
Matches the Mini Shai-Hulud campaign: 639 malicious versions across 323 packages in this wave.
fig. 02 · illustration · how the signals described above present the trigger package. They did not fire on May 19: the real block came from a known-malicious-version match added from Endor Labs' disclosure. The score is illustrative
Sources: CyberXYZ threat intelligence, with Endor Labs and Socket Threat Research disclosures (May 19, 2026). Full technical write-up on the CyberXYZ blog.