astropod sign in

Inside the AsyncAPI "Miasma" Attack: When the Pipeline Itself Becomes the Attacker

Published on gastropod.io 7-15-2026

On July 14, 2026, someone with push access to the AsyncAPI generator repository quietly landed a commit under a throwaway git identity — "Your Name," an invalid email address, nothing anyone would flag on sight. Twelve minutes later, the project's own release workflow did exactly what it was built to do: it built the package, signed it, and shipped it to npm.

That's the part worth sitting with. The attacker didn't steal an npm token, didn't compromise a maintainer's laptop, and didn't need to touch any install script. They got a commit into a branch that a GitHub Actions workflow trusted, and let the legitimate CI/CD pipeline launder the rest. The resulting packages — @asyncapi/generator, @asyncapi/generator-helpers, @asyncapi/generator-components, and @asyncapi/specs — carried valid OIDC provenance attestations the whole time. Combined, those packages see something like 3 million downloads a week.

The payload itself didn't rely on postinstall hooks either, which is notable given npm's more recent restrictions on install-time scripts. Instead, the malicious code sat inside the package's actual source files and activated the moment something require()'d the module during normal use — a build, a test run, a CI job. Once triggered, it spawned a detached background process that pulled a second-stage loader from IPFS, decrypted a roughly 3MB payload, and dropped what researchers are calling the Miasma tasking framework: a credential-stealing RAT with support for six separate command-and-control channels (HTTP, Nostr, IPFS, BitTorrent DHT, libp2p, even an Ethereum contract lookup), cross-platform persistence via systemd, launchd, and Windows Registry keys, and worm-like logic that tries to republish itself into any other packages the victim maintains.

A few outlets have noted the malware's references to "Miasma" and "Shai-Hulud" look more like deliberate misdirection than genuine attribution — deception aimed at researchers as much as at defenders.

Sources:

Why This One Is Different

Most of the supply chain incidents we write about here involve a stolen credential or a socially engineered maintainer handoff. This one didn't need either. The attacker found a gap in how the release pipeline evaluated what it was building, not who was building it — and every downstream signal (the signature, the OIDC attestation, the SLSA provenance) checked out perfectly, because from the pipeline's perspective, nothing was wrong. The workflow ran exactly as designed. It just built something it shouldn't have.

That's the uncomfortable part for anyone relying on provenance as a proxy for trust. A valid attestation proves that an authorized workflow produced an artifact — it says nothing about whether the commit that triggered the workflow deserved to be there. And because the malicious code lived in an ordinary source file, not an install hook, it wasn't the kind of thing a "block postinstall scripts" policy would ever see coming.

What Actually Would Have Helped Here

We'll be upfront: nothing catches a first-party compromise like this one at the door. The packages weren't typosquats, there was no namespace confusion, and the signature was real. Where a registry earns its keep in a case like this is what happens in the hours right after someone notices — and that part is worth looking at closely.

The moment any scanner in the org — yours, ours, or a third party's — flags anomalous behavior in one of these packages, that finding needs to attach to the exact artifact digest, not just sit in a dashboard. Gastropod's scanner findings ingest takes output from whatever you're already running (Trivy, Grype, Snyk, Anchore) and pins it to the PURL and sha256 of that specific version, so the next pull of that same digest anywhere in the org already carries the flag. From there, the blast-radius graph answers the question every incident responder asks first — which services actually pulled this — in one query instead of a fleet-wide grep, and the per-pull audit spine shows exactly who, from where, and when, so credential rotation can start immediately instead of after an afternoon of log archaeology.

The other piece is timing. These packages were live and spreading for hours before public advisories caught up — the gap between "we found it internally" and "the advisory is public" is where most of the damage happens. That's the case for federation: a sector lets a vetted group of orgs share a finding, including an embargoed one, the moment one of them catches it, well ahead of a public CVE. Nobody has to petition their way into a single central club to get that — you choose who's in your own sector.

The Bigger Pattern

This is at least the second high-profile npm campaign this year to borrow the "Miasma" and "Shai-Hulud" naming, whether through genuine reuse or deliberate misdirection, and the underlying technique — compromise the pipeline, not the token — is becoming the default playbook rather than the exception. Provenance tells you a trusted workflow ran; it doesn't tell you the commit behind it deserved to be there. Worth checking what your own registry actually knows about an artifact by the time someone has to ask.

← news