AGENTIC COMMONSAI industry briefings

繁中EN

TopicAI Coding & Developer ToolsPublished

All English articles

Shai-Hulud npm Worm Hits Mistral SDK; Provenance No Defense

On this page6 sections
  1. How One Fork Turned Into 170+ Packages
  2. The Payload Goes After the AI Developer's Machine
  3. Valid Provenance, Zero Protection
  4. Worm-Like Spread and the Revocation Trap
  5. The Response Checklist
  6. References

Summary: StepSecurity tracked the Mini Shai-Hulud npm worm on May 11, 2026, attributing it to TeamPCP and counting more than 170 affected packages, including Mistral SDKs. The attacker stole maintainer CI/CD credentials and pushed infected releases that carried cryptographically valid SLSA provenance. The payload harvested OIDC, cloud, SSH, wallet, and agent credentials, then persisted in developer tools and exfiltrated data through GitHub commits.

On May 11, 2026, npm was hit by a supply-chain worm capable of spreading itself. StepSecurity tracks the campaign as Mini Shai-Hulud and attributes it to a group it calls TeamPCP, whose playbook is to steal a maintainer’s CI/CD credentials and then automatically push infected releases for every package that maintainer controls. TanStack’s own post-mortem counted 84 malicious versions planted across 42 @tanstack/* packages, and the victim list has since grown past 170 — Mistral AI’s official SDKs included, with the fallout spilling onto PyPI.

One detail should stop any supply-chain program in its tracks: the malicious tarballs arrived carrying cryptographically valid SLSA provenance. Nothing about those attestations was forged. The worm had seized the projects’ own release pipelines, so each attestation correctly named the genuine builder, repository, and workflow.

How One Fork Turned Into 170+ Packages

The attack account (voicproducoes) was created on March 19 and then went quiet. It came back to life on May 10, forking TanStack/router and staging the payload in a commit. May 11 brought the tainted releases in a rapid run: @tanstack/react-router 1.169.5 and 1.169.8, @tanstack/history 1.161.9 and 1.161.12, and dozens more. From there the worm crossed into other namespaces — @opensearch-project/opensearch 3.6.2, @uipath/apollo-core 5.9.2, @draftlab/auth, safe-action.

Mistral’s own tracker confirmed the damage: mistralai/client-ts issue #217, opened May 11, named @mistralai/mistralai 2.2.4 as compromised. Going by StepSecurity’s list, 2.2.3 and 2.2.4 are the affected versions, while @mistralai/mistralai-azure and @mistralai/mistralai-gcp were struck at 1.7.2/1.7.3. The same wave also caught mistralai 2.4.6 and guardrails-ai 0.10.1 on PyPI.

The tampering leaves a tell that auditors can search for directly. Each poisoned tarball picked up one extra optionalDependencies entry along with a 2.3 MB obfuscated router_init.js sitting at the package root, and its size jumped from roughly 190 KB to 905 KB — a 3.7x difference. A size anomaly like this is still the cheapest alert you can wire up.

The Payload Goes After the AI Developer’s Machine

Reading the payload’s target list feels like reading an inventory of the modern AI developer machine. It scrapes the GitHub Actions Runner.Worker process through /proc memory to lift the ambient OIDC token, and it takes AWS IMDSv2, ECS, and Vault credentials as well. The harvest spans upward of 100 file paths: cloud keys, SSH keys, crypto wallets, Claude and Kiro configuration files, shell history. Persistence is installed in Claude Code, VS Code, and OS-level services, and a counterfeit “CodeQL Analysis” workflow goes in too — one built on toJSON(secrets) so every repository secret is dumped in a single pass.

The payload shifts to Bun 1.3.13 to stay under the radar of security tooling built for Node.js. Exfiltration was planned just as carefully: some of the data rides Session’s CDN, the rest lands in GitHub dead-drop commits written under the address claude@users.noreply.github.com, on Dependabot-lookalike branches that borrow their names from Dune. Whoever wrote this had an exact picture of what a developer machine holds in 2026.

Valid Provenance, Zero Protection

On the official SLSA blog, Andrew McNamara of Red Hat later broke the chain into its three steps. TanStack’s bundle-size.yml ran on the pull_request_target trigger, which meant fork-contributed code executed inside the trusted repository’s security context. The malicious code then poisoned the pnpm package store under a cache key the legitimate release workflow would later restore — GitHub Actions shares cache scope across trigger types. In the final step, the attacker, holding id-token: write, scraped the OIDC token from runner memory and published straight to npm, routing around the workflow’s conditional publish logic.

The blunt conclusion: a signed artifact is not automatically one you can trust. Provenance documents what took place; it offers no verdict on whether that was good enough. npm’s built-in provenance effectively tops out at SLSA Build L2, and this attack violated all three L3 isolation properties in one stroke — a shared cache was poisoned, the signing identity was exposed, and attacker code survived from one build into the next. The monitoring side had a hole too: both malicious CI runs ended with status “failure” and still published their packages. An alert tied to publish events from failed runs would have trimmed the exposure window by hours.

Worm-Like Spread and the Revocation Trap

The worm scans for npm tokens carrying bypass_2fa, walks the maintainer’s full package list, and publishes an infected release for each entry, using OIDC exchange to push them — growth is exponential by design. Nastier yet, one token in the haul comes with the description “IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner.” Order of operations matters: isolate and image the machine first, rotate credentials second. A hasty revoke may be the very trigger for the destructive wipe.

The Response Checklist

Install an affected version, and every secret in that environment has to be treated as burned. Fall back to the last clean version, remove node_modules, and reinstall from scratch. npm tokens, GitHub PATs, cloud keys, and SSH keys all need rotating, and wallet funds should be moved out of reach. Sweep repositories for injected workflows and go through the CI runs recorded after 2026-05-11T19:20Z. The structural work is equally concrete: gate or drop pull_request_target, run workflows with least-privilege permissions, pin actions by digest, and handle shared caches as trust boundaries. Agent configuration files belong in with your other secrets — the worm reached for Claude Code and Kiro configs before anything else. And where coding agents run inside your pipeline, sandboxing and approval policies are the next layer of defense to put in place (see our earlier piece on how OpenAI deploys Codex safely).

References

AGENTIC COMMONSOperated by PHLEGON LABS
ShareXEmail
Support us

Related reading

  1. Defender-Side Models: Anthropic Points Claude at OT and Open-Source Security

    Anthropic's Cyber Mission pairs frontier models with critical infrastructure providers and free OSS scanning — here's what builders should note.

    Anthropic

  2. NHS Retreats from Open Source; GDS Says Keep Code Open

    After AI bug-hunting jumped, NHS England moved to close nearly all its open source repos; May 14 GDS and DSIT guidance pushes back: keep code open by default and fix weaknesses.

    Security

  3. GPT-5.5 Instant System Card: What It Means for Product Builders

    OpenAI's GPT-5.5 Instant is the first Instant model rated High capability for cybersecurity and biosecurity. Learn what changed, how it works, and what to consider.

    AI Safety