Skip to content
HACKTECH
Supply chainReported Published 5 sources

Mini Shai-Hulud worm spans npm and PyPI; TanStack release pipeline abused

Microsoft Security Research identified a resurgence of the Shai-Hulud worm family on 11 May 2026, reporting more than 170 npm packages and 2 PyPI packages across 404 malicious versions and describing it as the first supply chain attack to simultaneously span both registries in a single coordinated operation. In the TanStack wave, tracked as CVE-2026-45321, the attacker chained a pull_request_target workflow, GitHub Actions cache poisoning and extraction of an OIDC token from runner memory to publish 84 malicious versions across 42 @tanstack packages between 19:20 and 19:26 UTC, all with valid SLSA provenance, according to TanStack and Tenable. In a later wave reported on 20 May, a compromised @antv maintainer account spread the worm to downstream packages, and Microsoft said GitHub removed 640 malicious packages and invalidated 61,274 npm granular access tokens that had write permissions and 2FA bypass.

  • Mini Shai-Hulud
  • npm
  • PyPI
  • TanStack
  • CVE-2026-45321
  • GitHub Actions
  • cache poisoning
  • OIDC
  • SLSA provenance
  • worms

What the sources report

  • Microsoft's 11 May finding named the malicious optional dependency @tanstack/setup; the payload persisted through a SessionStart hook in .claude/settings.json and spread by pushing .claude/setup.mjs and .claude/router_runtime.js into victims' repositories through GitHub GraphQL (Microsoft).
  • CVE-2026-45321 (CVSSv3 9.6): a pull request from a deliberately renamed fork triggered pull_request_target workflows that poisoned the GitHub Actions cache; the release workflow later restored that cache, and attacker code read an OIDC token from the Runner.Worker process memory and used it to publish directly to the npm registry (Tenable, TanStack postmortem).
  • TanStack's postmortem says the 84 versions across 42 packages were published on 11 May 2026 between 19:20 and 19:26 UTC, that no npm tokens were stolen, and that all 84 were deprecated about 1 hour 43 minutes after the first publish; Tenable says they carried valid SLSA Build Level 3 provenance from Sigstore and that TeamPCP published the worm's source code on 12 May 2026.
  • Microsoft (20 May): the @antv wave reached downstream packages including echarts-for-react; the payload exits unless running on GitHub Actions on Linux and scrapes Runner.Worker process memory for masked secrets.
  • SecurityWeek, citing Socket, put the full campaign at 1,055 versions across 502 unique packages and, citing StepSecurity, reported three malicious versions of Microsoft's durabletask Python SDK uploaded to PyPI within a 35-minute window; it presents the TeamPCP attribution as an inference from similarity to earlier attacks.
  • Tenable describes a gh-token-monitor daemon that polls GitHub every 60 seconds and triggers recursive file deletion if its token is revoked, and advises removing persistence before rotating credentials.

What it means for your organisation

TanStack says no npm tokens were stolen: code from an untrusted fork wrote to a cache that the trusted release job later restored, and the malware then obtained a publish-capable OIDC token from inside that job, so the packages carried valid provenance. Provenance shows where a package was built, not that the build was clean. The worm's token monitor also changes the order of incident response, because revoking a token before removing persistence can trigger file deletion.

What we check

  • Review pull_request_target and workflow_run workflows for execution of fork code, and confirm caches are not shared between fork-triggered and release workflows.
  • Check that jobs with id-token: write run in protected environments with required reviewers and do not restore caches written by untrusted jobs.
  • Audit npm tokens for write access with 2FA bypass, and check whether trusted publishing can replace them.
  • On suspected hosts, remove gh-token-monitor services and injected .claude/settings.json and .vscode/tasks.json entries before revoking tokens.
  • Check that CI enforces install-time controls: --ignore-scripts by default, exact version pins, lockfile integrity checks and a minimum release age.
  • A white-box review of your application: source code, architecture, dependencies and build pipeline. Automated analysis finds the candidates; reviewers confirm each one by reading the code path, and only confirmed defects reach the report, each with a file and line reference.

    Duration: 5 to 15 working days, depending on codebase size

  • Hands-on help when an attacker is already inside: triage on the first call, containment that does not destroy evidence, forensic scoping of what was touched, and recovery that we verify before calling it complete. Outside a crisis we run retainers, tabletop exercises and compromise assessments, so your team has practised the first hour before it happens.

    Duration: Live incidents until recovery is verified; readiness work in days

  • Facilitated workshops that map how a system or feature could be attacked before it is built or shipped. We draw the data flows with your engineers, walk them with STRIDE, rank the threats by likelihood and impact, and turn the result into backlog items and test cases your team owns.

    Duration: 2 to 5 days per system, remote or on site

  • An IAM-first review of AWS, Azure or GCP. We map what an attacker reaches after compromising one workload or one developer laptop, then rank those paths by the data at the end of each and write the Terraform or policy change that cuts it.

    Duration: 4 to 8 working days

Run these checks against your own systems

We pick the checks that apply to your systems. A 45-minute scoping call ends with a fixed quote and a proposed start date; the written scope follows by email.