# AsyncAPI npm packages compromised via a GitHub Actions pwn request

> On 2026-07-14 an attacker exploited a `pull_request_target` misconfiguration in `asyncapi/generator` to steal a highly-privileged GitHub PAT, then published five malicious `@asyncapi/*` releases through the project's own trusted GitHub Actions release pipeline - valid npm OIDC provenance and all. The payload fires on `require()`, spawns a detached Node process, fetches an 8.25 MB IPFS loader (Miasma), and installs a 3.09 MB implant with six independent C2 channels (HTTP, Nostr, IPFS, BitTorrent DHT, libp2p GossipSub, Ethereum smart contract). Combined weekly downloads: ~2.9M.

- Published: 2026-07-14
- Last updated: 2026-07-24
- Severity: critical
- Kind: Compromise - A legitimate, already-used package, maintainer account, CI pipeline, or release tag was hijacked and a malicious version was published under a name people already depend on.
- Ecosystems: npm
- Scope: 4 packages, 5 compromised versions
- Tags: ci-cd-compromise, credential-theft, infostealer, obfuscation, account-takeover
- Threat actor: Miasma
- Also known as: AsyncAPI Miasma compromise, AsyncAPI pwn request compromise, M-Red-Team AsyncAPI
- Detected by: Socket, Datadog Security Labs, StepSecurity, Aikido, Wiz, OX Security, Chainguard, SafeDep, Microsoft Security
- Incident ID: npm-2026-07-14-asyncapi-miasma-actions-pwn-request

## Affected packages (4)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [@asyncapi/generator](https://dependencywatch.io/package/npm/@asyncapi/generator) | npm | 3.3.1 |
| [@asyncapi/generator-components](https://dependencywatch.io/package/npm/@asyncapi/generator-components) | npm | 0.7.1 |
| [@asyncapi/generator-helpers](https://dependencywatch.io/package/npm/@asyncapi/generator-helpers) | npm | 1.1.1 |
| [@asyncapi/specs](https://dependencywatch.io/package/npm/@asyncapi/specs) | npm | 6.11.2-alpha.1, 6.11.2 |

## What happened

On 2026-07-14 at approximately 05:03 UTC an attacker (GitHub user `elzotebo999`, subsequently deleted and now displayed as "ghost") opened the first of 37 spam pull requests against `asyncapi/generator`. At 05:08 UTC the attacker authored malicious commit `47be388`; at 05:11 UTC a `pull_request_target`-triggered `Docs Preview (Netlify)` workflow ran with the repository's privileged GITHUB_TOKEN and organization-scoped PAT in scope. By 05:17 UTC the workflow had exfiltrated the PAT to a Rentry paste. Between 05:40 and 07:05 UTC a series of malicious commits were force-pushed to the repository's `next` branch. At **07:10:42 UTC** the project's legitimate release workflow triggered on the poisoned `next` branch and published the first malicious tarball - the compromise had, from PR-open to malicious-release-live, taken about two hours and seven minutes.

## Package + version manifest

Exact publish timestamps confirmed against the public npm registry `time` map:

| Package | Malicious version | Publish (UTC) | Clean predecessor |
|---|---|---|---|
| `@asyncapi/generator-helpers` | `1.1.1` | 2026-07-14 07:10:42 | `1.1.0` |
| `@asyncapi/generator-components` | `0.7.1` | 2026-07-14 07:10:44 | `0.7.0` |
| `@asyncapi/generator` | `3.3.1` | 2026-07-14 07:10:48 | `3.3.0` |
| `@asyncapi/specs` | `6.11.2-alpha.1` | 2026-07-14 08:06:20 | `6.11.1` |
| `@asyncapi/specs` | `6.11.2` | 2026-07-14 08:30:09 | `6.11.1` |

`@asyncapi/specs` accounts for approximately 2.7M of the ~2.9M combined weekly downloads across the four packages. The `alpha.1` publish is unusual for AsyncAPI's stable-release cadence and appears to be either a probe or a fallback for lockfiles pinned to alpha channels - the same malicious payload shipped in both `alpha.1` and the stable `6.11.2`.

## Attack chain - pwn request against `pull_request_target`

[Datadog Security Labs' reconstruction](https://securitylabs.datadoghq.com/articles/compromised-asyncapi-npm-packages/) and [StepSecurity's CI-side analysis](https://www.stepsecurity.io/blog/compromised-next-branch-pushes-malicious-asyncapi-generator-generator-helpers-and-generator-components-to-npm) both attribute the entry to a **`pull_request_target` "pwn request" vulnerability** in the `Docs Preview (Netlify)` workflow. The workflow was configured to check out the PR HEAD (attacker-controlled code) while running with the repository's privileged secrets in scope. PR `#2155` - one of 37 spam PRs in the burst - modified files under `apps/generator/docs/` in a way that caused the workflow to execute attacker-controlled JavaScript with the repository's GITHUB_TOKEN and a highly-privileged organization-scoped PAT accessible.

The attacker exfiltrated the stolen PAT to a Rentry paste URL and then used the PAT out-of-band to force-push malicious commits directly to the `next` branch (bypassing branch protection because the PAT had admin-level scope). When the project's legitimate release workflow triggered on that branch, it published tarballs derived from the attacker's code - **with valid npm OIDC provenance attestations**, because the release workflow itself is the trusted publisher. `npm audit signatures` PASSES on the malicious tarballs.

## The payload - Miasma botnet loader

The malicious code is embedded in normal runtime modules (not lifecycle scripts) and executes on `require()` or `import`. On load it:

1. Uses `child_process.spawn` to launch a **detached** `node -e` process (`.unref()`'d, hidden from installer process tree).
2. Fetches an encrypted 8.25 MB JavaScript loader from IPFS CID `QmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9`, saves it locally as `sync.js`.
3. Decrypts a 3.09 MB implant (744 bundled modules) using an attacker public key (`0432fa4ba871877d94081fe83323fa24dfa1491e9de8725cbab7b734de9e9be3b233ef6742fd6264437c9532223d687b05fa540b70af6a516b8539af84d0eeb48e` - secp256k1).
4. Establishes six parallel C2 channels: HTTP to `85.137.53.71:8080/8081/8091`, Nostr relay, IPFS-based command retrieval, BitTorrent DHT rendezvous, libp2p GossipSub P2P mesh, and Ethereum contract callbacks at `0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710`.
5. Harvests browser passwords/cookies (Chrome, Brave, Firefox, Edge), SSH keys, npm/GitHub tokens, AWS/GCP credentials, macOS Keychain, Slack/Discord/Telegram tokens, crypto wallets.
6. Establishes persistence by writing malicious task definitions into `.vscode/tasks.json` and `.claude/settings.json` in the victim's home directory - the implant re-launches whenever the developer next opens VS Code or Claude Code.

The payload family is the same **Miasma** botnet loader documented in [Aikido's Miasma variant writeup](https://www.aikido.dev/blog/asyncapi-npm-packages-compromised-with-miasma-variant) and previously observed in the [Miasma / `redhat-cloud-services` June cluster](https://dependencywatch.io/incident/npm-2026-06-01-miasma-redhat-cloud-services). The AsyncAPI variant is the largest-blast-radius Miasma delivery to date.

## Remediation status

All five malicious versions have been **unpublished** from the public npm registry (not merely deprecated - the tarballs no longer resolve). The current dist-tag `latest` for each package points at the clean predecessor. However:

- Private registry mirrors (Verdaccio, Artifactory, Nexus, Cloudsmith) will keep serving the cached tarballs until an operator manually evicts them.
- Build images baked between 2026-07-14 07:10 UTC and the unpublish still contain the malicious code and remain live until re-baked.
- The AsyncAPI project has [published an official incident report](https://github.com/asyncapi/community/discussions/1953) and a post-mortem committing to migrate away from `pull_request_target` on all publish-adjacent workflows.

## Context - three high-profile GitHub-Actions supply-chain compromises in eight days

This is the third public npm supply chain incident in eight days rooted in GitHub Actions / repository-side compromise:

- **2026-07-08** - [`@injectivelabs/sdk-ts` 17-package wallet-drain burst](https://dependencywatch.io/incident/npm-2026-07-08-injectivelabs-sdk-ts-crypto-wallet-drain), delivered via maintainer GitHub account takeover.
- **2026-07-11** - [Jscrambler `jscrambler` + plugins](https://dependencywatch.io/incident/npm-2026-07-11-jscrambler-rust-infostealer), delivered via stolen npm publish token.
- **2026-07-14** - this AsyncAPI Miasma delivery via `pull_request_target` pwn request.

The pattern is a shift away from typosquats toward compromise of legitimate high-download packages via CI/CD or maintainer-account weaknesses - an arc that Palo Alto Networks' [npm threat landscape monitoring](https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/) has been flagging since Q2 2026.

## Impact

- Any Node.js process that `require()`d or `import`ed `@asyncapi/generator@3.3.1`, `@asyncapi/generator-components@0.7.1`, `@asyncapi/generator-helpers@1.1.1`, `@asyncapi/specs@6.11.2`, or `@asyncapi/specs@6.11.2-alpha.1` during the exposure window (2026-07-14 07:10 UTC → unpublish, roughly 24–36 hours) must be treated as fully compromised - the payload runs at import time, not just install time, so `--ignore-scripts` provides zero mitigation
- **Massive transitive blast radius**: `@asyncapi/specs` alone carries ~2.7M weekly downloads and is a direct dependency of AsyncAPI CLI, [Kong Insomnia](https://github.com/Kong/insomnia/issues/10252), Postman workspaces, and many enterprise API-tooling stacks; combined weekly downloads across the four packages exceeds 2.9M. Any project that pulled the malicious version through a transitive AsyncAPI dependency inherited the full Miasma implant
- The [Miasma](https://dependencywatch.io/incident/npm-2026-06-01-miasma-redhat-cloud-services) loader harvests: browser saved passwords and cookies (Chrome, Brave, Firefox, Edge), SSH keys, npm and GitHub tokens, AWS credentials, macOS Keychain, and cryptocurrency wallet data. Persistence is achieved through injection into `.vscode/tasks.json` and `.claude/settings.json` on the victim's workstation - meaning the implant survives reboot AND continues to fire whenever the developer opens VS Code or Claude Code
- The implant is a **command framework with six independent C2 channels** (HTTP, Nostr relay, IPFS, BitTorrent DHT, libp2p GossipSub P2P mesh, Ethereum smart contract callback at `0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710`). Blocking any single egress channel does not neutralize the implant; six channels means single-egress firewalls will not stop C2
- The malicious versions were published through the AsyncAPI project's own **legitimate GitHub Actions release workflow with valid npm OIDC provenance attestations** - meaning `npm audit signatures` PASSES on these tarballs. Provenance-based trust checks that expect "if OIDC-signed then benign" will not flag these publishes
- Reveals a class of `pull_request_target` GitHub Actions vulnerability the security community calls a **"pwn request"**: a PR that touches a specific path (`apps/generator/docs/`) triggered a `Docs Preview (Netlify)` workflow running with the repository's privileged GITHUB_TOKEN and organization-scoped PAT in scope - the attacker chained a run of the workflow to exfiltrate the PAT to a Rentry paste and then used the PAT to force-push malicious commits to protected branches

## What to do

1. Grep every lockfile (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `deno.lock`) for the five malicious version pins: `@asyncapi/generator@3.3.1`, `@asyncapi/generator-components@0.7.1`, `@asyncapi/generator-helpers@1.1.1`, `@asyncapi/specs@6.11.2`, `@asyncapi/specs@6.11.2-alpha.1`
2. Pin back to the clean predecessors: `@asyncapi/generator@3.3.0`, `@asyncapi/generator-components@0.7.0`, `@asyncapi/generator-helpers@1.1.0`, `@asyncapi/specs@6.11.1`. All five malicious versions are now UNPUBLISHED from the public npm registry - but a private mirror (Verdaccio, Artifactory, Nexus, Cloudsmith) that cached them will keep serving them until manually purged
3. If any host installed or `require`d a malicious version: rotate ALL credentials that the affected process (or a developer using the same workstation) could reach - npm tokens, GitHub PATs and GitHub CLI config, SSH keys, AWS/GCP/Azure cloud credentials, browser-saved passwords, Slack/Discord/Telegram tokens, crypto wallets. Miasma implants persist through VS Code and Claude Code settings - inspect `.vscode/tasks.json` and `.claude/settings.json` on the affected workstations for injected `command` / `runTask` / `postCommand` entries
4. Block outbound traffic to the known IOCs while incident-responding: primary HTTP C2 at `85.137.53.71` (ports 8080, 8081, 8091), IPFS gateway fetch of `QmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9`, and Ethereum contract callbacks to `0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710`. Note that the implant's six-channel design means blocking these will not stop all C2, only make the operator's job harder
5. Audit every GitHub Actions workflow in your organization that uses `pull_request_target` - the [OWASP CI/CD Security Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/CI_CD_Security_Cheat_Sheet.html) and [Chainguard's pwn request writeup](https://www.chainguard.dev/unchained/asyncapi-supply-chain-compromise-npm-packages-backdoored-via-github-actions) both flag `pull_request_target` triggers that check out the PR HEAD as a top-tier misconfiguration. Migrate to plain `pull_request` where possible; when `pull_request_target` is required, do NOT check out the PR HEAD, do NOT expose repository secrets, and gate the workflow behind `if: github.event.pull_request.head.repo.full_name == github.repository`
6. If your organization publishes npm packages through GitHub Actions with npm OIDC trust, review the workflow scoping: the malicious AsyncAPI tarballs shipped with valid provenance because the workflow itself was hijacked. Consider requiring `environment:` gating with manual approval on all publish jobs, and rotate the OIDC trust relationship if any actor-authored commit merged in the last 30 days
7. Assume the Miasma operator has multi-week persistence on any affected developer workstation. Full re-image (not just `npm uninstall`) is the safe reset for a workstation that installed a malicious tarball

## Check your own dependencies

- Check a package-lock.json against this incident: https://dependencywatch.io/check/package-lock-json

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [Compromised npm Packages in the AsyncAPI Namespace Deliver Multi-Stage Miasma Botnet Malware](https://socket.dev/blog/asyncapi-supply-chain-attack) - Socket
- [Compromised AsyncAPI npm packages: inside a CI supply-chain attack](https://securitylabs.datadoghq.com/articles/compromised-asyncapi-npm-packages/) - Datadog Security Labs
- [Coordinated AsyncAPI Supply Chain Attack: Miasma RAT Delivered via Compromised CI/CD Pipelines in Two Repositories](https://www.stepsecurity.io/blog/compromised-next-branch-pushes-malicious-asyncapi-generator-generator-helpers-and-generator-components-to-npm) - StepSecurity
- [AsyncAPI npm packages compromised with Miasma variant](https://www.aikido.dev/blog/asyncapi-npm-packages-compromised-with-miasma-variant) - Aikido
- [AsyncAPI npm packages backdoored via GitHub Actions](https://www.aikido.dev/blog/asyncapi-npm-packages-backdoored-via-github-actions) - Aikido
- [M-Red-Team: AsyncAPI Supply Chain Compromise via GitHub Actions](https://www.wiz.io/blog/m-red-team-asyncapi-supply-chain-compromise-via-github-actions) - Wiz
- [AsyncAPI npm organization compromised, 2M weekly downloads affected](https://www.ox.security/blog/asyncapi-npm-organization-compromised-2m-weekly-downloads-affected/) - OX Security
- [AsyncAPI supply chain compromise: npm packages backdoored via GitHub Actions "pwn request" (July 2026)](https://www.chainguard.dev/unchained/asyncapi-supply-chain-compromise-npm-packages-backdoored-via-github-actions) - Chainguard
- [Inside the AsyncAPI npm supply chain attack](https://cloudsmith.com/blog/inside-the-asyncapi-npm-supply-chain-attack) - Cloudsmith
- [AsyncAPI Packages Compromised with Miasma RAT](https://safedep.io/asyncapi-generator-supply-chain-attack-miasma-rat/) - SafeDep
- [Compromised AsyncAPI npm Packages Deliver Multi-Stage Botnet Malware](https://thehackernews.com/2026/07/compromised-asyncapi-npm-packages.html) - The Hacker News
- [AsyncAPI npm Supply Chain Attack: Malware Injected Into Packages With 2 Million Weekly Downloads](https://securityaffairs.com/195395/security/asyncapi-npm-supply-chain-attack-malware-injected-into-packages-with-2-million-weekly-downloads.html) - Security Affairs
- [Four AsyncAPI npm packages carry Miasma botnet loader](https://www.developer-tech.com/news/four-asyncapi-npm-packages-miasma-botnet-loader/) - Developer Tech
- [Unpacking the AsyncAPI npm supply chain compromise and import-time payload delivery](https://www.microsoft.com/en-us/security/blog/2026/07/15/unpacking-asyncapi-npm-supply-chain-compromise-import-time-payload-delivery/) - Microsoft Security
- [@asyncapi/generator on npm - package page](https://www.npmjs.com/package/@asyncapi/generator) - npm
- [@asyncapi/specs on npm - package page](https://www.npmjs.com/package/@asyncapi/specs) - npm

---

Canonical page: https://dependencywatch.io/incident/npm-2026-07-14-asyncapi-miasma-actions-pwn-request
Markdown version: https://dependencywatch.io/incident/npm-2026-07-14-asyncapi-miasma-actions-pwn-request.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
