· 6 min read

Someone Open-Sourced a Self-Propagating npm Worm and Started a $1,000 Contest to Weaponize It. The Mini Shai-Hulud Campaign Is Already at 170+ Packages.

On May 12, 2026, a group calling itself TeamPCP published the source code for the Shai-Hulud worm on GitHub under an MIT license, then announced a $1,000 contest on a breach forum for the largest supply-chain attack built with it. The campaign that followed, tracked as Mini Shai-Hulud, has compromised more than 170 packages across npm and PyPI, packages with over 518 million cumulative weekly downloads. It's a self-propagating worm: it steals developer and cloud credentials, then uses them to spread further.

A week ago I'd have told you the scary supply-chain story was TrapDoor, the credential-stealer hitting npm, PyPI, and Crates that targeted crypto and AI developers. This is the same threat class with one nasty new wrinkle: the tooling is now free, public, and contest-incentivized.

Why open-sourcing the worm is the actual story

The scale numbers will get the headlines, but the structural change is what should worry you. Until now, running a self-propagating supply-chain worm took real skill: you had to write the propagation logic, the credential harvesting, the validation, the persistence. That skill floor kept the number of capable actors small.

Publishing the source under a permissive license and attaching a bounty to it demolishes that floor. Now anyone who can clone a repo and read a README can run a credential-harvesting worm. The contest actively recruits people to do it and rewards whoever does the most damage. You're no longer defending against a handful of sophisticated groups; you're defending against everyone who wanted to try and previously couldn't.

That's the part that changes your threat model. The probability that a random package you pull in this month is carrying something malicious just went up, because the supply of attackers went up.

What the worm does

The mechanics are familiar from the TrapDoor and earlier Shai-Hulud campaigns. A compromised package runs a payload on install. It scans the machine for credentials and developer secrets: cloud keys, tokens, SSH keys. It validates what it finds against the relevant APIs. It establishes persistence. And critically, it uses the stolen credentials to publish or compromise more packages, which is what makes it a worm rather than a one-shot stealer. Each infected developer becomes a launch point for the next wave.

The install-time execution is the key detail. Most of this fires through lifecycle scripts that run automatically when you npm install or pull a Python dependency. You don't have to run the code. You just have to install the package.

The 30-minute defense

You can't audit 518 million downloads' worth of packages by hand. What you can do is close the doors the worm walks through. This is the same checklist that would have blunted Laravel-Lang and TrapDoor, and it holds up here.

Disable install scripts by default. In npm, set ignore-scripts=true in your .npmrc and enable scripts only for the specific packages that genuinely need them. The single biggest reduction in attack surface, because it kills the install-time execution the worm depends on.

Pin everything and verify integrity. Commit your lockfile, use exact versions, and let the integrity hashes do their job. A worm that compromises a new version can't hit you if you're pinned to a known-good one and your CI fails on a hash mismatch.

Get long-lived credentials off developer machines. The worm's whole business model is harvesting and validating cloud keys. If there's no standing AWS key in your shell environment or your ~/.aws/credentials, there's far less to steal. Use short-lived, scoped tokens. Rotate anything that's been sitting around.

Scope your CI tokens to the minimum. A CI pipeline running npm install on untrusted dependency updates is exactly where this spreads. Least-privilege tokens, no broad publish rights sitting in CI env vars, and ideally a separate restricted environment for dependency installs.

Audit before you upgrade. Don't blind-bump dependencies. Check the changelog, check the publish date and the maintainer, and be suspicious of a sudden flurry of new versions from an account. That wave pattern is exactly how these campaigns push compromised releases.

What this does and doesn't change

Honest take: nothing in that checklist is new, and that's the point. The defense against a free, contest-driven worm is the same hygiene that defends against a sophisticated one. If you already disable install scripts, pin versions, and keep long-lived keys off your machines, your exposure barely moved. The campaign is louder, not smarter.

What did change is the base rate. More attackers means more compromised packages means a higher chance that the next thing you install is carrying a payload. If you've been meaning to set ignore-scripts and clean the standing credentials off your laptop, this is the weekend. Thirty minutes of plumbing against a threat whose cost of entry just dropped to zero is the best trade on your board right now.

And don't let the open-source framing fool you into thinking this is someone else's problem because you're small. The worm doesn't target you specifically; it spreads to whoever installs an infected package, and a solo operator's laptop with a live cloud key on it is exactly as useful to it as a Fortune 500 engineer's. The contest rewards breadth. You're in scope.

Author

Sources

Stay in the Loop

Get new posts delivered to your inbox. No spam, unsubscribe anytime.

Newsletter coming soon. Set PUBLIC_CONVERTKIT_FORM_ID in .env to activate.

Related Posts