Mini Shai-Hulud and the Worm that Brought its own Provenance
)
Yes we like Dune. No we do not like this vulnerability.
May 12, 2026
If you've spent any time in the supply chain security trenches over the last year, you've watched the bar move. We are no longer talking about typosquatting a sloppy maintainer's package. We are talking about worms that hijack a project's own CI/CD, mint cryptographically attested malicious releases, and ship them to the same
npm install your team ran ten minutes ago.Mini Shai-Hulud, the campaign The Hacker News reported on this week, attributed to TeamPCP, is the cleanest example we have yet. 170+ packages across npm and PyPI. 518 million cumulative downloads in the blast radius. Forty-two TanStack packages, eighty-four versions. A CVSS 9.6 (CVE-2026-45321). And, for the first time on record, a worm that produces validly attested malicious packages with SLSA Build Level 3 provenance.
That last point is the one I'd underline twice. The thing that was supposed to give you confidence in a release - a signed provenance trail tying the artifact back to a real GitHub Actions run - is the thing the attacker is forging legitimately, by compromising the run itself.
What the worm actually does
The mechanics are worth understanding, because they tell you where the defensible chokepoints are.
The payload arrives one of two ways: an obfuscated
router_init.js embedded in the tarball, or a package.json whose preinstall hook fires a Bun-executed setup.mjs. Either way, once it lands on a developer workstation or a CI runner, it does what credential stealers do — except the target list is the 2026 version of the kitchen sink: cloud provider creds, crypto wallets, AI tooling, messaging apps, and CI system tokens including GitHub Actions OIDC.Stolen data flows out to
filev2.getsession[.]org over Session Protocol, which is the part designed to slip past enterprise filtering. As a fallback, the malware commits encrypted credential dumps to attacker-controlled GitHub repos via the GraphQL API — over 400 of those have been catalogued, helpfully labeled "Shai-Hulud: Here We Go Again."On the propagation side, the worm finds publishable npm tokens with
bypass_2fa enabled, enumerates every package that maintainer can publish to, and, this is the nasty part, exchanges stolen GitHub OIDC tokens for per-package publish tokens. It hijacks the real TanStack/router workflow, poisons the Actions cache, scrapes OIDC tokens from the runner's memory, and publishes through the legitimate pipeline. The provenance is real because the build was real. It was just the build of something you didn't ask for.And just so the defenders don't have an easy day: a dead-man's switch polls
api.github.com/user every sixty seconds, and if the npm token gets revoked, the malware fires rm -rf ~/ on the host. The token is even named IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner. Microsoft's analysis also caught geofenced destructive logic in the mistralai@2.4.6 PyPI package — country-aware checks that introduce a 1-in-6 chance of rm -rf / on Israeli and Iranian systems.This is not a clever undergrad. This is operational tradecraft against the developer ecosystem.
What "remediation" actually means here
The first impulse on the response side is to start revoking tokens. Don't — at least not yet. The Hacker News write-up flags this and we'd echo it: image the affected runners and developer machines before pulling any npm tokens, because the wiper trigger is tied to revocation. Rotate after you've captured state, not before.
The longer-term remediation is the harder conversation. The standard supply chain playbook — pin SHAs, audit your dependency graph, verify SLSA provenance — assumes the build was honest. Mini Shai-Hulud breaks that assumption. The build was honest. The attacker just owned the runner that performed it.
So the question we keep coming back to with our customers is: what does the runner do that a legitimate build wouldn't? And almost without exception, the answer is talk to places it has no business talking to.
Legitimate builds reach
github.com, the package registry, your container registry, your artifact store, and a small handful of well-known infrastructure endpoints. They do not reach filev2.getsession[.]org. They do not reach api.masscan[.]cloud or 83.142.209[.]194. They do not poll api.github.com/user every sixty seconds from a worker step that isn't supposed to know who the user is. The network footprint of compromise looks nothing like the network footprint of a real build, and that gap is where we built CargoWall.How CargoWall changes the math
CargoWall is an eBPF-based L4 firewall around every Actions runner. It runs a DNS proxy on the runner itself, intercepts every hostname lookup, dynamically pins the resolved IPs into a kernel-level allowlist, and drops anything else at the TC eBPF layer before it leaves
eth0. It also rewires the Docker daemon so containerized workload egress sees the same policy.For Mini Shai-Hulud specifically, that means:
- Exfiltration to
filev2.getsession[.]orgdoesn't happen. It's not on the allowlist, the DNS proxy refuses the query, and the eBPF program drops any direct-IP attempt. Same story forapi.masscan[.]cloudand the raw83.142.209[.]194endpoint. - The fallback GitHub-GraphQL exfiltration is constrained.
api.github.comis legitimately on most allowlists, so CargoWall isn't a silver bullet here — but the dead-man's-switch polling, the attacker-controlled GitHub repo creation, and the OIDC-token-monitoring service all generate network patterns you can see in CargoWall's audit logs, scoped to the workflow run. - The pre-install network reach-out fails closed. It doesn't matter that the malicious
setup.mjsran insidenpm install. The moment it tries to fetch its second-stage payload from an attacker-hosted host, CargoWall blocks it at the kernel. No payload, no persistence. - Sudo lockdown prevents firewall bypass. A compromised step that tries to disable CargoWall mid-workflow gets refused. The malware can't unhook what it can't reach.
- Audit mode lets you find your real surface first. Before flipping to
enforce, run CargoWall inauditacross your busiest workflows for a week. You'll have a clean inventory of every host your CI legitimately needs — and a fast way to spot the ones it doesn't.
The honest part of the pitch: CargoWall is a network-layer control. It does not undo a
preinstall hook that ran locally, and it does not validate the package you installed. What it does is sever the post-execution dependency on the attacker's infrastructure — and for a worm whose entire model depends on phoning home, hijacking OIDC, and re-publishing through stolen tokens, that is the layer that turns a campaign into a non-event.Where we go from here
If you operate GitHub at any meaningful scale, this is the year network egress policy on your runners stops being optional. The provenance trail you've been relying on is now an attack surface. The OIDC tokens you've been minting are now exchange currency for publish rights you didn't grant. And the developers on your team are running, in good faith, packages whose only crime is being downstream of a maintainer who hadn't yet rotated a token.
We built CargoWall because we believe the runner is the new perimeter. Mini Shai-Hulud is a reminder that the cost of treating it like one is much lower than the cost of not.
If you want to get a CargoWall policy in front of your workflows in the next hour, the cargowall-action repo has a quickstart. Run it in audit mode first. Look at what your CI actually touches. Then close the door.
C
CodeCargo Team
The CodeCargo team writes about GitHub workflow automation, developer productivity, and DevOps best practices.
)