Breach analyses · 2026-05-11 · NPM Supply chain · Propagation worm
Mini Shai-Hulud: 170+ npm packages, valid provenance, scanners passed.
The May 11, 2026 npm supply-chain worm. The defining incident: a malicious package that carried valid SLSA provenance. Provenance verification and signature checks passed, so the versions published and were downloaded before behavioral scanners flagged them minutes later. The attack was state-divergent, not content-malicious.
Reference: Wiz Research · Snyk Disclosure
Facts of the incident
What we know.
First compromise
2026-05-11: 84 malicious versions across 42 @tanstack packages, pushed in a rapid burst through TanStack's own CI using npm OIDC trusted publishing. No publisher account or npm token was stolen.
Packages affected
170+ including TanStack, Mistral AI client, Guardrails AI
Provenance
VALID SLSA attestation. Same CI workflow signature. Existing scanners passed.
Payload behavior
A setup.mjs preinstall script plus a ~2.3 MB obfuscated router_init.js added to the tarball, wired in via a new optionalDependencies entry pointing at a raw GitHub commit. It harvests 100+ credential file paths (GitHub PATs, npm, AWS, HashiCorp Vault, Kubernetes and CI/CD tokens) and extracts an OIDC token from the Actions runner to mint a valid npm credential. Exfiltration ran over the Session network (filev2.getsession.org) and GitHub dead-drop repos.
Detection method
Automated behavioral scanners, not manual maintainer notice: Socket's AI Scanner flagged each compromised version within six minutes of publication, and StepSecurity's AI Package Analyst flagged them within minutes.
Detection time
~6 minutes to first automated detection; days to map the full campaign (April 29 to May 13, 2026).
Why existing tooling missed it
Provenance is necessary but not sufficient.
SLSA, Sigstore, npm provenance: these are real defenses against an attacker who lacks build-pipeline credentials. They prevent forged provenance.
Mini Shai-Hulud bypassed provenance by compromising the maintainer's build pipeline first. Once inside the legitimate pipeline, the attacker's publishes carry legitimate SLSA attestations. The signature is valid because the signing identity was stolen, not forged.
Point-in-time scanners ask: "does this package have known-bad signals right now?" The compromised packages had no known-bad signals at the moment of publish. The signals that mattered were relative to the package's own history, not absolute.
How SCG state-divergence detection would catch this at version 1
Six divergence signals, all from the worm's actual signature.
Preinstall script newly added
+30Baseline: Absent or stable across prior versions
Compromise version: New setup.mjs preinstall script present in compromised version 1
Publish-rate burst anomaly
+35Baseline: 1-4 publishes per month per package
Compromise version: 84 versions across 42 packages pushed in one rapid CI-driven burst
Outbound network egress to fresh domains
+25Baseline: No network calls in prior versions
Compromise version: Exfil to the Session network (filev2.getsession.org) and typosquat domains (git-tanstack.com)
Cross-package hash collision
+50Baseline: Independent payloads across packages
Compromise version: Same router_init.js payload hash appears across many @tanstack packages
OIDC token extraction
+40Baseline: No runtime credential reads
Compromise version: Extracts an OIDC token from the Actions runner (process memory) to mint an npm credential
Dependency tree delta
+15Baseline: ±0-2 deps per minor release
Compromise version: New deps added; some with their own divergence signals
SCG's divergence score sums weighted signals. Thresholds: <20 allow · 20-49 alert · 50-79 require HITL · ≥80 deny. Mini Shai-Hulud version 1 scored well over 100 on every compromised package. State-aware detection is designed to catch it on first publish, before signature databases have ever seen it, once SCG ships (public beta Q1 2027).
The four-layer defense
SCG is designed to ship as four composable surfaces.
Registry Mirror
One config line: registry=https://registry.synoi.systemsSilent default. Every npm install verified inline against the divergence index. Zero developer behavior change.
Supply Chain PR Bot
Install GitHub App once per orgBrand-visible PR comments on every package-lock.json diff. Shows divergence verdict per pinned (version, integrity) pair.
Lockfile Verifier
None - runs as CI stepBelt-and-braces for orgs that won't change registry. synoi-verify package-lock.json queries the OID Resolver.
Verified Publisher
Wrap publish in release script + HITL surfacePublisher-side gate. Stolen npm token alone can't ship - every publish requires out-of-band human approval via SMS / Slack / system tray.
Supply Chain Guard is in active development; public beta Q1 2027.
The Lockfile Verifier and PR Bot are first to ship - free tier, zero friction. Registry Mirror and Verified Publisher follow. A public OID Resolver at oid.synoi.systems will be the federation moat once deployed; it is not live yet.