Security Digest · Jul 14, 2026 · Supply-chain compromise · CI/CD
AsyncAPI npm Packages Backdoored via pull_request_target
A pwn-request workflow let attackers publish RAT-laced @asyncapi/specs and generator releases on Jul 14, 2026. Import-time payload; check lockfiles and rotate.
Our verdict
Check exposure
If any build resolved @asyncapi/specs 6.11.2 or the July 14 generator releases, treat that machine as backdoored; everyone else should still fix their own pull_request_target workflows.
Who must act: Anyone whose lockfile, cache or CI run picked up @asyncapi/specs 6.11.2 or 6.11.2-alpha.1, @asyncapi/generator 3.3.1, generator-helpers 1.1.1 or generator-components 0.7.1 on or after July 14, 2026, including via transitive dependencies.
Who can relax: Projects whose lockfiles stayed on @asyncapi/specs 6.11.1 and generator 3.3.0 or earlier through July 14-15; the bad versions have since been removed from npm.
- Affected
- @asyncapi/specs 6.11.2-alpha.1 and 6.11.2
@asyncapi/generator 3.3.1
@asyncapi/generator-helpers 1.1.1
@asyncapi/generator-components 0.7.1 - Fixed in
- @asyncapi/specs 6.11.1 (last clean; current latest tag)
@asyncapi/generator 3.3.0 or later clean releases
@asyncapi/generator-helpers 1.1.0
@asyncapi/generator-components 0.7.0 or later clean releases - CVSS
- Not scored
- EPSS
- n/a
- CISA KEV
- Not listed
- Exploitation
- Exploited in the wild
- Severity
- Critical
What to do
- Search lockfiles, artifact mirrors and CI caches for the five malicious versions, including transitive @asyncapi/specs pulls.
- Pin @asyncapi/specs to 6.11.1 (or a later clean release) and purge npm/Yarn caches on shared runners.
- On hosts that imported a bad version, kill detached node processes, delete the NodeJS/sync.js drop and persistence, then reimage if possible.
- Rotate npm, GitHub, SSH, cloud and browser-stored credentials from a clean machine.
- Audit your own workflows: never check out pull-request head code in a pull_request_target job that has secrets or a write token.
How to check if you are affected or compromised
- grep lockfiles for '@asyncapi/specs@6.11.2', 'generator@3.3.1', 'generator-helpers@1.1.1' and 'generator-components@0.7.1'.
- Look for sync.js under ~/.local/share/NodeJS, ~/Library/Application Support/NodeJS or %LOCALAPPDATA%\NodeJS, a miasma-monitor systemd user unit or HKCU Run value, and ~/.config/.miasma/.
- Search network logs for 85.137.53.71 on ports 8080, 8081 and 8091, and for IPFS fetches of CID Qmet4fhsAaWMBUxNDfREHwgiyDeSWy4YSYs9wiKUW5jGyf.
What happened#
On July 14, 2026, attackers published five malicious versions of four packages in the @asyncapi npm scope in about 90 minutes. The packages were @asyncapi/specs 6.11.2-alpha.1 and 6.11.2, @asyncapi/generator 3.3.1, @asyncapi/generator-helpers 1.1.1 and @asyncapi/generator-components 0.7.1. Microsoft Threat Intelligence traced the entry point to a docs-preview workflow in asyncapi/generator. That workflow ran on pull_request_target and checked out the untrusted PR head, with a privileged token and repository secrets in reach. This is the classic "pwn request" pattern. A commit pushed to PR #2155 at 05:08 UTC set it off minutes later.
The attacker then pushed commits as the asyncapi-bot account. Microsoft says the workflow exposed the bot's personal access token. In issue #2184, AsyncAPI maintainers say the workflow is the likely path but not confirmed. The pushed commits matched the project's release triggers, so AsyncAPI's own trusted-publishing workflows built and published the poisoned packages. They carried valid provenance attestations linking them to the real repositories. Microsoft notes the weakness had been flagged in a proof of concept on April 29, and a fix proposed in May was still under review.
The payload uses no install scripts. Code injected into index.js and library files runs when the module is imported or required. It spawns a hidden, detached Node.js process that fetches an encrypted sync.js from IPFS and evaluates it. Microsoft identifies the result as the Miasma runtime, campaign miasma-train-p1: a remote-access toolkit with shell, file transfer and proxying, and C2 at 85.137.53.71. Its credential-harvesting modules were disabled in this build, but they can be switched on remotely. Chainguard lists browser passwords, SSH keys, npm and GitHub CLI tokens, cloud credentials and wallets as targets.
Who is affected#
@asyncapi/specs is the big one. It had about 2.6 million downloads in the week before the attack, and many AsyncAPI tools pull it in transitively, so you may never have listed it yourself. Microsoft saw the first downstream fetch of 6.11.2 into a Yarn cache at 08:49 UTC, 19 minutes after it was published. The bad versions are gone from the registry, and the latest tag for specs points at 6.11.1. Lockfiles, private mirrors and CI caches may still hold the bad versions.
Do you really need to act?#
Check, then act if you find a hit. A project whose lockfile kept @asyncapi/specs at 6.11.1 was not exposed. Two details make this one easy to underestimate:
--ignore-scriptsdoes not help. The trigger is an import, so any test run, build or CLI invocation that loaded the package ran the loader.- Provenance checks passed. The packages were built by the real pipeline from unauthorized commits, so "has a provenance attestation" did not mean "safe".
Even if you never touched AsyncAPI, the root cause is worth fixing in your own repositories. Any pull_request_target job that checks out PR code while holding secrets or a write token can be taken over the same way.
What to do now#
- Search:
npm ls @asyncapi/specs @asyncapi/generatorandgrep -nE '@asyncapi/(specs@6\.11\.2|generator@3\.3\.1|generator-helpers@1\.1\.1|generator-components@0\.7\.1)' package-lock.json yarn.lock pnpm-lock.yaml. - Pin clean versions (specs 6.11.1, generator 3.3.0, helpers 1.1.0, components 0.7.0, or later clean releases). Add an
overridesentry for transitive specs. Then runnpm cache clean --forceoryarn cache cleanon shared runners. - On hit hosts, kill detached
nodeprocesses, remove thesync.jsdrop and persistence, and rebuild runners and base images from a known-good state. - Rotate npm, GitHub, SSH, cloud and browser-saved credentials from a clean machine.
- Audit workflows:
grep -rn pull_request_target .github/workflows. Never combine that trigger with a checkout of the PR head when secrets are present. Microsoft also recommends npm CLI 11.10.0 or later, or amin-release-agecooldown.
How to tell if you were hit#
Microsoft and Chainguard publish file hashes for all five tarballs and injected files. On disk, look for sync.js in a NodeJS folder (~/.local/share/NodeJS, ~/Library/Application Support/NodeJS or %LOCALAPPDATA%\NodeJS), a miasma-monitor.service user unit or a miasma-monitor Run key, or ~/.config/.miasma/run/node.lock. On the network, look for connections to 85.137.53.71 on ports 8080, 8081 and 8091, and for IPFS gateway fetches of CID Qmet4fhsAaWMBUxNDfREHwgiyDeSWy4YSYs9wiKUW5jGyf. The OSV record for specs also lists four older versions (6.8.2, 6.8.3, 6.9.1, 6.10.1) flagged in an earlier entry. Block those too.
Timeline#
- — A proof of concept demonstrates the workflow weakness (per Microsoft).
- — 05:08 UTC: a malicious commit is pushed to PR #2155. Around 07:10: three generator packages are republished. At 08:06 and 08:30: specs 6.11.2-alpha.1 and 6.11.2. Issue #2184 is filed the same day. Maintainers then rotate tokens, disable the preview workflows and get the versions removed from npm.
- — Microsoft publishes its analysis.
- — Maintainers report continued Actions hardening across the org.
Sources
Original sources first: vendor and project advisories, CVE and government records, the discoverers’ write-ups. Every claim above links to one of these. See how the Security Desk works.
Original and primary sources
- Microsoft Threat Intelligence — Unpacking the AsyncAPI npm supply chain compromise and import-time payload delivery microsoft.com
- GitHub — asyncapi/generator issue #2184: malicious versions published (maintainer response) github.com
- OSV — MAL-2025-190643: Malicious code in @asyncapi/specs (npm) osv.dev
- npm registry — @asyncapi/specs package metadata registry.npmjs.org
- npm — @asyncapi/specs downloads, Jul 6-12, 2026 api.npmjs.org
- Chainguard — AsyncAPI supply chain compromise: npm packages backdoored via GitHub Actions pwn request chainguard.dev