top of page

Shai-Hulud V3 Forged SLSA Attestations for 416 Packages — TanStack, Mistral, Bitwarden, SAP. The Chain of Trust Held. They Hijacked the Keys.

  • Writer: Patrick Duggan
    Patrick Duggan
  • 12m
  • 5 min read

We've been tracking the Shai-Hulud family since December 4, 2025. V2 was the self-propagating npm worm. The April 29 Mini variant from TeamPCP hit SAP npm and pivoted to target Claude Code. May 11 brought another wave we indexed within hours. Today, May 13, brings V3 — and V3 is a different shape.


This one didn't bypass the signing chain. It got the signing chain to sign for it.


The reported scope, per StepSecurity, Endor Labs, Aikido, Socket, SafeDep, Microsoft Threat Intelligence, and Snyk, is 416 malicious artifacts across npm and PyPI. The TanStack namespace alone took 84 malicious versions across 42 packages. Mistral AI, Guardrails AI, UiPath, OpenSearch, Bitwarden CLI, and SAP all sit on the victim list. Every single one of those malicious versions was published carrying valid SLSA Build Level 3 provenance attestations issued by npm's own signing infrastructure.


If you are running a package-verification policy that trusts SLSA attestations, that policy currently waves these malicious versions through.



What changed between V2 and V3


V2 was a worm. It read package.json files in compromised maintainer environments, identified other packages those maintainers had publish rights to, and pushed itself onward. The propagation mechanism was credential reuse and the trust between adjacent maintainers. We wrote the anatomy on April 25.


V3 is not propagation. V3 is provenance.


The attack chain has three links. First, a misconfigured GitHub Actions workflow trigger called pull_request_target. That trigger runs the workflow with the repository's secrets even when the pull request comes from a fork. Second, GitHub Actions cache poisoning. Third, OpenID Connect token theft from the runner's memory while the workflow is mid-flight.


The chain converts a forked pull request into a stolen OIDC token. The OIDC token is what npm's signing infrastructure uses to mint provenance attestations. With a stolen token, the attacker publishes their malicious package version through the legitimate CI/CD pipeline, and npm dutifully attests that the package was built from the maintainer's repository on a clean runner. The attestation is mathematically valid. The signature is real. The chain of trust verifies green.


The package payload is malicious anyway.



Why TanStack matters specifically


TanStack is the package family behind React Query, React Table, React Router, and the broader Tanner Linsley ecosystem. If you write modern React, you have transitive dependencies on a TanStack package whether you imported one directly or not. Vercel, Netlify, Cloudflare Pages, and most React-shaped enterprise frontends pull TanStack through somebody two layers up the tree.


84 malicious versions across 42 packages is not a single bad release. It is a campaign that took advantage of the fact that TanStack maintains many small packages and that the CI/CD infrastructure for all of them shares the same workflow shape. Compromise the shape once, mint attestations for every package in the namespace.


The Mistral AI compromise is interesting for a different reason. The same credential-stealing payload is dropping on both Mistral and TanStack victims, but the trigger mechanism is different. The Mistral compromise was a targeted hit on a high-profile AI company. The TanStack compromise was a saturation hit on a high-volume package ecosystem. Same operator, two playbooks, one Tuesday afternoon.



The IOCs you can act on today


Three command-and-control domains have surfaced across the investigations. The first is api.masscan.cloud, which is unrelated to the legitimate masscan project — the attackers chose a name that would look plausible in egress logs. The second is git-tanstack.com, which is exactly the kind of look-alike domain you would expect for a campaign that wants its outbound traffic to read as TanStack telemetry. The third is the wildcard subdomain pattern under getsession.org.


If you have egress visibility, those three signatures are the cheapest first hunt. If you operate a SIEM, our STIX feed at analytics dot dugganusa dot com slash api slash v1 slash stix-feed will carry them as soon as they are indexed.



The receipt — why we are not late to this


We covered Shai-Hulud V2 on December 4, 2025, when most observers were still calling it an isolated package compromise. We named it as a worm, mapped the propagation pattern, and added it to the Pattern 38 supply chain family. On April 25 we updated with the V2 anatomy as the worm's behavior matured. On April 29 we covered TeamPCP's Mini Shai-Hulud hitting SAP npm and pivoting to target Claude Code specifically — the first time a supply chain attack named a single coding-assistant integration as its target. On May 11 we documented another wave that hit just before Canvas paid the ShinyHunters ransom.


Five months of continuous coverage. Today's V3 is the family's evolution from credential reuse to provenance hijack, and the Pattern 38 family now needs a sub-classification for attestation abuse versus signature theft.


The threat-intel discipline that lets us hit V3 the day of disclosure is the Bloom filter novelty check plus the Meilisearch cross-index correlation. The Bloom filter knows we have not seen the new IOCs before, which routes them through ingest rather than through deduplication. The cross-index correlation joins the new IOCs against the entire prior Shai-Hulud family in milliseconds, surfacing whether the C2 infrastructure overlaps with V2 or with the Mini variant. Today's results say: the C2 infrastructure is fresh, the payload signature overlaps with the Mini variant, and the attestation-abuse primitive has no prior in our index. That is what novelty looks like when you measure it instead of guess at it.



What defenders should do this week


Three things, in order of leverage.


First, audit your package-verification policy if you have one. If your policy accepts SLSA attestations as proof of integrity, you currently have no defense against V3. The fix is not to abandon attestations — they are still useful against most of the threat surface — but to add an additional check on publication-time anomalies: maintainer-not-recently-active, version-jump-too-large, dependency-tree-too-changed, sudden-post-install-script. The provenance is real. The publication is anomalous. You verify the anomaly, not the chain.


Second, audit your GitHub Actions for pull_request_target triggers. That single trigger is the front door for the V3 attack chain. If a workflow runs with repository secrets while accepting code from a fork, you have an OIDC token theft surface. The remediation is to either remove the trigger, restrict the workflow to a labeled-by-maintainer condition, or split the workflow so the part that runs with secrets does not have access to the forked code.


Third, hunt your egress logs for the three C2 signatures listed above. They will be cheap to filter and the cost of being wrong is one false positive per environment. The cost of skipping the hunt is whatever the credential-stealing payload exfiltrates from your CI environment between now and when the next vendor pushes detections.



Where we sit


The Pattern 38 supply chain family has been our hardest beat for fifteen months. V3 is not the worst incarnation we expect — we expect a version that combines V2's propagation with V3's attestation abuse, and that one will be very hard to remediate. The current 416-artifact scope will probably grow over the next 72 hours as the vendors finish their inventories.


We will index the IOCs as they surface. The STIX feed is free at ten queries per day. If you operate at scale, the Pro tier is $99 per month and gives you 2,000 queries per day plus the OPNsense and Suricata feed formats.


Better luck next Tuesday is the operational reality. The next variant is being prepared right now.


— Patrick Duggan, May 13, 2026




How do AI models see YOUR brand?

AIPM has audited 250+ domains. 15 seconds. Free while still in beta.


Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page