A Supply Chain Attack That Reproduces
Most supply chain compromises are events. A maintainer account gets phished, a malicious version ships, defenders pull it, and the incident closes. The Shai-Hulud worm is a different category of problem, because it does not wait to be distributed. It spreads itself. In a fresh June 2026 surge, the worm compromised more than 100 packages across the npm and PyPI ecosystems, and researchers cataloged north of 470 malicious artifacts as the campaign rolled on. This is not a single poisoned package. It is an outbreak with a reproduction mechanism built in.
The name comes from the great sandworms of Dune, and the metaphor is apt: it burrows through the dependency tree and surfaces wherever it finds purchase. The mechanism is brutally elegant. As researchers describe it, the worm scans the local system and connected cloud services for credentials, API keys, tokens, and other secrets, then uses them to spread itself by infecting the packages the victim has access to. Compromise one developer with publish rights to a dozen packages and the worm now has a dozen new vectors, each leading to more developers and more secrets.
Miasma and Hades: Two Heads of the Same Worm
The June wave showed up under two variant names mapped to the two ecosystems. On npm, the variant tracked as Miasma weaponized the install process, using a malicious binding.gyp file that executes during installation. Researchers tied it to dozens of npm packages and over 300 malicious versions, with notable targets including packages under a Red Hat hybrid cloud namespace, a Vapi server SDK, and various deployment and AI tooling packages. The genius and the menace are the same: the payload runs at install time, before any code review or runtime sandbox can intervene.
On PyPI, the variant called Hades took a parallel approach tuned to Python. It planted setup.pth files that execute automatically at Python startup, an even quieter trigger than an install hook. The PyPI waves targeted bioinformatics, graph machine learning, and packages themed around the Model Context Protocol, the connective tissue of the new agentic AI tooling stack. That target selection is not random. AI and data science developers tend to hold rich cloud credentials and operate in environments where pip install is reflexive, making them an efficient population for a credential-harvesting worm to colonize.
Install-Time Execution Is the Core Weakness
Both variants exploit the same structural flaw in modern package ecosystems: installing a package is allowed to run arbitrary code. The npm install hook and the PyPI startup file are different doors into the same room. The moment a developer or a continuous integration runner pulls a dependency, attacker-controlled code executes with that environment's full privileges, which on a build server often means access to cloud credentials, signing keys, and the very publishing tokens the worm needs to propagate. The attack does not need a vulnerability in your code. Your willingness to run install scripts is the vulnerability.
That is what makes self-propagating malware so dangerous in this setting. A traditional malicious package has a blast radius defined by its download count. A worm has a blast radius defined by the connectivity of the entire developer graph, because every infected maintainer becomes a new distribution point. The campaign reportedly pivoted its delivery mechanisms every couple of days, swapping techniques to stay ahead of detection. By the time one wave is cleaned up, the credentials it stole have already seeded the next, which is precisely the dynamic that turns containment into a moving target.
The Defenders Are Watching, but the Model Is Strained
The response has been broad. A roster of security vendors including Socket, Snyk, Sonatype, StepSecurity, Ox Security, Endor Labs, and Harness tracked the waves, published indicators, and worked with the registries to pull malicious versions. That coordination matters and has blunted individual waves. But the recurring pattern, a worm that resurfaces every few months with new packages and refreshed techniques, exposes how reactive the open source security model still is. Detection and takedown happen after publication, which means after install-time execution has already fired on the machines that pulled the package first.
The deeper issue is trust by default. The npm and PyPI ecosystems were built on the assumption that packages are benign and maintainers are honest, and most are. But that assumption hands attackers a permissionless distribution network with millions of trusting endpoints and an execution primitive on installation. As long as installing a dependency means running its code, worms like Shai-Hulud have everything they need: a way in, a way to steal, and a way to spread. The vendors can keep mowing the lawn, but the soil keeps growing more.
What Engineering Leaders Should Do Now
Treat the dependency tree as hostile until proven otherwise. Pin every dependency to an exact version and use lockfiles, so an automatic upgrade cannot silently pull a poisoned release. Disable install scripts wherever your tooling allows it, because lifecycle hooks are the single most exploited primitive in these campaigns. Run installs and builds in isolated, least-privilege environments that hold no standing cloud credentials, so a worm that executes at install time finds nothing worth stealing and nowhere to spread. These are not exotic controls, they are the difference between a near miss and an outbreak.
Most importantly, assume some secrets have already leaked and rotate accordingly. The currency of this worm is credentials, so the most valuable thing you can do is make stolen credentials worthless: short-lived tokens, scoped permissions, and aggressive rotation. Audit which publishing tokens and cloud keys are reachable from a build runner and shrink that set to the minimum. Shai-Hulud will return, the way it has returned before. The organizations that survive the next wave will be the ones who decided in advance that running a stranger's code on install is a privilege to be revoked, not a convenience to be assumed.



