Three Attacks, One Week, One Lineage
Shai-Hulud is not a single piece of malware — it is a lineage of self-propagating npm and PyPI worms, first documented in 2025, that share a signature behavior: steal publishing credentials from a compromised package or CI environment, then use those credentials to automatically trojanize and re-publish other packages the stolen credentials have access to. Each generation spreads without further human involvement from the attacker, which is what makes the family dangerous — and what makes each new wave worth naming and studying on its own.
June 2026 produced three variants worth separating clearly, because they targeted three different surfaces and each requires a different defense:
- Miasma — an npm-focused worm, first identified June 1
- Hades — a PyPI variant that surfaced days later, with a cross-runtime payload
- IronWorm — not a new worm mechanically, but a new payload technique: poisoning AI coding assistant configuration files to turn the developer's own tooling into the exfiltration channel
Miasma: How It Started
The first confirmed infections were traced to Red Hat's Hybrid Cloud Console JavaScript ecosystem, where 32 packages were found carrying a payload containing the string "Miasma: The Spreading Blight" — a signature left either carelessly or deliberately by the operators, consistent with the Shai-Hulud family's history of embedding taunting strings in its payloads.
From that initial foothold, Miasma behaved exactly as its lineage predicts: using credentials
harvested from the first compromised packages to automatically publish trojanized versions of
other packages reachable from those same accounts and CI tokens. By June 5, researchers had
identified at least 57 affected npm packages and more than 300 malicious package versions, with
confirmed hits including the Vapi server SDK and a cluster of smaller but widely-depended-on
utilities — ai-sdk-ollama, autotel, awaitly,
executable-stories, node-env-resolver, and wrangler-deploy.
Notably, several of the affected packages sit in the AI-tooling and deployment-automation corners of the npm ecosystem — exactly the packages most likely to run with elevated CI/CD permissions and access to cloud credentials, which is consistent with the worm's core strategy: compromise packages that unlock the widest possible blast radius per infection.
Hades: PyPI's Turn, and a Cross-Runtime Trick
Shortly after Miasma was contained on npm, researchers identified a related variant on PyPI,
carrying the string "Hades – The End for the Damned." The first wave affected roughly 19 packages,
each shipping a malicious *-setup.pth file — a mechanism Python's site initialization
process executes automatically at interpreter startup, well before any application code runs.
Hades' .pth payload did not just run Python code — it fetched the Bun JavaScript
runtime and used it to execute a JavaScript payload from a pure-Python package install. This
strongly suggests the Miasma and Hades operators share payload infrastructure across ecosystems,
rather than maintaining separate npm and PyPI toolchains. A scanner that only understands
Python-native threats would miss the actual second-stage payload entirely.
A second Hades wave landed on June 8, adding roughly 29 more packages, this time concentrated in bioinformatics libraries, graph machine learning tooling, and — again — MCP-themed packages, reinforcing that AI-adjacent tooling is where this campaign is deliberately hunting for its highest-leverage targets.
IronWorm: When the Attack Targets Your AI Assistant
The most novel development of the week was not a new distribution mechanism — it was a new
payload target. Packages associated with the June wave were found injecting .cursorrules
and CLAUDE.md files into infected projects, using zero-width Unicode characters to
hide instructions inside content that looks, to a human skimming the file, like ordinary
project configuration.
When a developer opens the infected project in Cursor or Claude Code, the AI assistant reads those files as legitimate project-level instructions — which is exactly what they are designed to do — and, following the hidden directive, runs what appears to be a routine "security scan" that in fact exfiltrates local secrets: API keys, cloud credentials, and tokens sitting in environment files or credential stores on the developer's machine.
| Variant | Ecosystem | Entry Point | Distinct Behavior |
|---|---|---|---|
| Miasma | npm | Compromised publishing credentials | Self-propagating re-publish to reachable packages |
| Hades | PyPI | *-setup.pth at interpreter startup |
Fetches Bun runtime to run a cross-language JS payload |
| IronWorm | npm / PyPI (payload technique) | Zero-width Unicode injection in .cursorrules / CLAUDE.md |
Turns the developer's own AI assistant into the exfiltration channel |
Why Lockfiles and a Point-in-Time SBOM Didn't Catch This
This is not a "known vulnerable version" problem, and that distinction matters. Traditional SCA tooling is built to answer: does this dependency have a disclosed CVE? Miasma and Hades are not disclosed CVEs when they land — they are legitimate-looking package versions, published by accounts with valid (if stolen) credentials, that no vulnerability database has scored yet. A lockfile pins you to a version; it does not tell you whether that version was the one the maintainer actually intended to publish.
Detecting this class of attack requires capabilities most organizations have not prioritized: behavioral analysis of new package versions before they are trusted, monitoring for anomalous publish activity on dependencies you rely on, and — as of this attack wave — treating AI assistant configuration files as untrusted input that deserves the same code review scrutiny as a CI script.
Practical Response Steps
- Audit your dependency tree against the confirmed package lists for Miasma and Hades, including transitive dependencies, not just direct ones.
- Rotate any credentials that may have been present on machines running an infected package, including npm and PyPI publishing tokens themselves.
- Review
.cursorrules,CLAUDE.md, and equivalent AI-assistant configuration files in every repository as if they were executable code — because, functionally, they now are. Watch specifically for zero-width or otherwise invisible Unicode characters. - Restrict or audit postinstall and
.pth-style automatic execution in CI environments wherever your build process allows it. - Adopt provenance attestation (npm provenance, Sigstore-signed PyPI packages) where your dependencies support it — it does not stop a compromised-credential publish, but it materially raises the cost of a convincing one.
Continuous Monitoring Beyond Known CVEs
Fossity's continuous SBOM monitoring flags newly published versions of your dependencies against behavioral and provenance signals — not just CVE databases — so a compromised-credential publish like Miasma or Hades surfaces as an anomaly before it becomes a CVE. Diff every SBOM against the last known-good state and catch drift the moment it happens.
Monitor Beyond Known CVEs with Fossity →The Uncomfortable Pattern
Three campaigns, one lineage, eight days, three different attack surfaces — a registry, a language runtime, and a developer's own AI tooling. The direction of travel is unmistakable: attackers are following wherever elevated trust and automation concentrate, and in mid-2026 that is increasingly the AI-assisted development workflow itself. An SBOM tells you what is in your software. It is becoming just as important to know what is in the tools that write your software.