# TeamPCP's Mini Shai-Hulud Is Back: A Self-Spreading Supply Chain Attack Compromises TanStack npm Packages

TeamPCP worm hijacked TanStack's GitHub Actions OIDC tokens via a pull_request_target Pwn Request and cache poisoning to publish 84 malicious npm versions with valid SLSA provenance.

- Payout: Real-world hack
- Severity: critical
- Program: TanStack
- Analysis by: StepSecurity
- Disclosed: 2026-05-12
- Write-up quality: 9/10
- Original: https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem
- Library page: https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem
- Tags: area:cloud domain:infra domain:oss impact:data-leak impact:mass-exploit kind:incident platform:threat-intel sev:critical tech:github-actions tech:nodejs technique:chained vuln:secrets-leak

**Target:** npm packages / GitHub Actions CI/CD release pipeline
**Root cause:** A pull_request_target Pwn Request plus GitHub Actions cache poisoning let attacker code run in the trusted release workflow, which then extracted the ambient OIDC token (id-token: write) from Runner.Worker process memory and used it to publish directly to npm, bypassing the workflow's own publish step.
**Steps:**
1. Attacker forks TanStack/router (account voicproducoes) and commits 79ac49ee adding fake @tanstack/setup package.json with `prepare: bun run tanstack_runner.js && exit 1` and a 2.3MB obfuscated tanstack_runner.js
2. Inject `optionalDependencies: {"@tanstack/setup": "github:tanstack/router#79ac49ee..."}` and router_init.js into published tarballs outside the normal build
3. Trigger the release workflow via pull_request_target Pwn Request + Actions cache poisoning so malicious code executes in the trusted pipeline
4. Payload runs `gh auth token`, then `sudo python3 | tr -d '\0' | grep -aoE '"[^"]+":{"value":"[^"]*","isSecret":true}' | sort -u` reading /proc/<Runner.Worker>/mem to dump all secrets
5. Use stolen ACTIONS_ID_TOKEN_REQUEST_TOKEN/URL to get a Fulcio cert and generate SLSA v1 provenance, then POST to `registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/<pkg>` to mint per-package publish tokens
6. Publish infected tarballs for every package by the maintainer (registry search `maintainer:<user>`), then exfiltrate via filev2.getsession.org and GitHub GraphQL createCommitOnBranch dead-drops authored as claude@users.noreply.github.com
**How found:** StepSecurity AI Package Analyst detected anomalous package publications; runtime analysis under Harden-Runner showed bun.exe connecting to git-tanstack.com and api.github.com during npm install, and a process tree revealing python3 reading /proc/<pid>/mem of Runner.Worker.
**Exploitation:** Worm executes at npm install via the github: optionalDependency prepare hook, installs Bun to evade Node --require hooks, scrapes Runner.Worker memory for all secrets, harvests 100+ credential paths (cloud, SSH, wallets, AI tools, VPN, messaging), queries AWS IMDSv2/ECS/Vault, then self-propagates by minting npm publish tokens via OIDC exchange and republishing infected versions of every package the stolen maintainer controls. Persistence via Claude Code SessionStart hook, VS Code folderOpen task, and launchd/systemd gh-token-monitor services; exfil through Session Protocol CDN and GitHub GraphQL dead-drop commits.
**Escalation:** Chained CI compromise -> OIDC token theft -> valid SLSA Build L3 provenance -> npm publish -> maintainer enumeration -> cross-maintainer worm spread to UiPath, DraftLab, Mistral, OpenSearch, etc.; injected codeql_analysis.yml workflows using toJSON(secrets) for persistent repo-wide secret exfil.
**Insight:** SLSA provenance only attests which pipeline built an artifact, not that the pipeline was uncompromised — so audit release workflows for pull_request_target + cache poisoning paths that let attacker code run alongside id-token: write, and treat any package whose tarball contains files outside its `files` field (e.g. router_init.js at root) as tampered.
