Supply Chain Worm

Hades worm trojanizes six PyPI packages with a Bun runtime stealer

June 19, 2026·9 min read·Chris Boker, Founder
Hades wave of the Mini Shai-Hulud campaign trojanizes six PyPI bioinformatics packages and self-propagates across PyPI and npm

Around June 8, 2026 a fresh wave of the broader Mini Shai-Hulud campaign that researchers have been tracking since June 1 swept through PyPI, and inside a window measured in under a minute the attackers used stolen maintainer tokens to publish trojanized versions of six bioinformatics packages, namely embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, and pyphetools, that quietly ship a JavaScript credential stealer the moment a developer or CI agent imports any of them (Socket, Endor Labs). The Hades sub-wave is one of three related self-propagating worm clusters that the group tracked as TeamPCP has been running in parallel since June 1, and across PyPI and npm the combined Mini Shai-Hulud, Miasma, and Hades clusters have now passed 473 compromised package artifacts, including 32 official @redhat-cloud-services npm packages republished after a breach of the RedHatInsights GitHub organization, and a steady run of fresh hits against TanStack, UiPath, DraftLab, and the wider AI and MCP developer tooling ecosystem (SecurityWeek, BleepingComputer).

Quick status: If any developer workstation or CI agent installed embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, or pyphetools from PyPI on or after June 8, 2026, or pulled an @redhat-cloud-services npm package on or after June 1, 2026, treat the host as compromised, remove every affected version, and rotate every credential, SSH key, and registry token that ever lived on it before the worm cycles those tokens into the next publish round.

What makes the Hades wave novel is the trojanized native extension, where the malicious payload rides inside a renamed .abi3.so file packaged alongside the legitimate wheel so a static Python source review never sees it, and the import hook then drops out of Python into the Bun JavaScript runtime to run a credential stealer that reads the maintainer token store, the pip and npm configuration, environment variables holding cloud and registry keys, and any SSH material it can reach, then attempts to publish a malicious version of every other package on which the captured maintainer holds write access (Socket, Tenable). Because the payload is an opaque native binary and the propagation engine runs under a separate language runtime, neither a Python static analysis pass nor an npm advisory feed catches the link on its own, and the broader worm family is now tracked under CVE-2026-45321 across both registries (SC Media, Tenable).

Why this class of compromise slips through a normal queue

A standard vulnerability management workflow watches CVE feeds, KEV listings, and vendor advisories, and that sensor set is structurally blind to a campaign that lives inside package registries and self-propagates faster than NVD can mint a number, because the Hades wave published its six bioinformatics packages in under a minute, which means any team that pulled fresh wheels on June 8 was already running the stealer before the first writeup landed, and the cross-runtime construction means the obvious detections that a Python-focused SCA tool runs against requirements.txt are looking in the wrong place because the bridge into the credential theft path is a Bun-launched JavaScript worker that the SCA tool was never written to inspect (Endor Labs).

Most security programs also tend to underweight bioinformatics, MCP tooling, and developer side projects in their software inventory, because those dependencies enter the build chain through individual researcher workstations or AI assistant configurations rather than through a centrally managed catalog, and the bioinformatics packages caught in the Hades wave are reach dependencies for academic and clinical research groups whose host inventories rarely sit inside a CTEM scope at all. The Miasma branch of the same campaign already proved how brutal that gap is when it abused RedHatInsights' own GitHub Actions OIDC trust to republish 96 versions of 32 official @redhat-cloud-services npm packages on June 1, and the Hades branch extends the same propagation logic into a registry, PyPI, that many enterprise teams still treat as a research playground sitting outside their CI inventory (BleepingComputer, SecurityWeek).

Prioritizing with TRIS

A raw CVSS triage cannot rank this event cleanly because the affected packages do not share a single product CPE, the malicious behavior only lights up at import time, and the worm spreads as fast as maintainer tokens are captured, so the queue that decides what gets handled today has to be driven by signal layered well beyond vendor scoring. TRIS, the multi-layer Threat and Risk Intelligence Scoring built into CVEasy AI, weighs the three signals that actually decide where this finding belongs in your queue inside your environment, and the Hades wave lights up on every one of them.

  • Active exploitation. The Hades wave shipped live to PyPI on June 8, the Miasma wave shipped live to npm on June 1, both worms continue to publish fresh malicious versions as new accounts fall, and Socket, Endor Labs, and Tenable are all tracking ongoing in-the-wild abuse, which TRIS treats as confirmed exploitation rather than a theoretical proof of concept (Socket, Tenable).
  • Blast radius. More than 473 malicious artifacts now span PyPI and npm under the combined TeamPCP cluster, the captured maintainer accounts include the keys to bioinformatics research workflows and to official Red Hat cloud packages, and the propagation engine multiplies the surface every time a new account falls, so the affected set keeps growing without any external trigger (SecurityWeek).
  • Real exposure. TRIS narrows the alert to hosts in your environment that pulled any of the six bioinformatics packages, the affected @redhat-cloud-services npm versions, or any of the TanStack, UiPath, and MCP packages flagged in the broader cluster, then enriches the queue with the specific malicious version numbers so the response collapses to the hosts that need an immediate credential rotation (SC Media).

Remediation steps

  1. Audit your Python and npm dependency trees against the known malicious version lists for embiggen, ensmallen, gpsea, phenopacket-store-toolkit, ppkt2synergy, pyphetools, the @redhat-cloud-services scope, and the wider Shai-Hulud advisories, cross-referenced against Socket, Endor Labs, OSV.dev, and Tenable's running FAQ (Socket, Tenable).
  2. Remove every malicious version on disk, pin each package to a verified pre-June 1 release or the publisher's confirmed safe version, then rebuild every wheel and lockfile that referenced an affected name so no stale .abi3.so artifact survives in a wheel cache or build container (Endor Labs).
  3. Rotate every GitHub token, AWS, GCP, and Azure key, npm and pip publisher token, and SSH key that ever lived on a host that installed or imported an affected package, because the stealer reads exactly those artifacts and the worm uses captured tokens to attempt fresh malicious publishes within minutes of capture (BleepingComputer).
  4. Review your CI secret stores and any maintainer accounts whose tokens were used to publish in the last ten days, since a captured account is the campaign's preferred next hop, and revoke anything that cannot be tied to a clean owner action (Tenable).
  5. Turn on PyPI and npm provenance attestation, hash pinning, and dependency review for every research and developer team that has been treated as out of scope, so the next wave lands inside your CTEM inventory rather than under it (SC Media).
The fix is removal plus rotation plus inventory. Removing every affected version closes the active payload, rotating every credential the host ever held closes the second-order access the stealer already opened, and pulling research and developer registry consumption into a real inventory closes the structural gap that has let the broader TeamPCP cluster run for nearly three weeks across PyPI and npm.

How CVEasy AI surfaces this

When a registry side worm of this shape spreads through PyPI and npm, CVEasy AI ingests the Socket, Endor Labs, Tenable, and vendor writeups within minutes, runs the combined picture through TRIS against the actual dependency inventory living on your own hardware, and answers the questions that decide the next forty eight hours, namely which hosts pulled an affected package between June 1 and today, which still carry an .abi3.so artifact or a Bun runtime drop from the install, which maintainer accounts in your supply chain show a publication pattern consistent with capture, and which credentials need rotation before the worm cycles through them again. As the number one local-first CTEM platform, CVEasy AI keeps the dependency inventory and the response loop entirely on your side of the wire, and feeds the BASzy attack validation module a clean target set so the team can prove the cleanup and rotations landed before the next sub-wave of the campaign moves through.

References

The next registry worm will not wait for an advisory to land in NVD.

CVEasy AI ingests registry side supply chain intelligence as it appears and ranks your real exposure with TRIS, on your own hardware, in minutes.

Related Reading