Skip to content

Back to the catalog

How Unprotected Release Branches Let Attackers Compromise AsyncAPI | Blog | Endor Labs
endorlabs.comwriteup

How Unprotected Release Branches Let Attackers Compromise AsyncAPI | Blog | Endor Labs

Endor Labs researchers found that AsyncAPI's release branches lacked branch protection, allowing an attacker with write access (or via a compromised contributor account) to push malicious commits that would be picked up by the automated release/publish pipeline, potentially poisoning published packages. The issue highlights how missing branch protection rules combined with automated CI/CD release workflows create a supply-chain compromise path for widely-used open-source projects.

TL;DR Unprotected release branches in AsyncAPI's GitHub repo could let an attacker push malicious code into automated release pipelines and compromise published packages.
Document

What it is

On July 14, 2026, five official @asyncapi npm packages were published carrying obfuscated remote-code-execution loaders. Affected: @asyncapi/specs@6.11.2 (a core transitive dependency of the parser, CLI, and generator trees), plus @asyncapi/generator and generator-family workspace packages at versions 3.3.1 / 0.7.1 / 1.1.1. The payload is a build of a malware framework internally branded Miasma (related to the Shai-Hulud lineage), deployed here in a "training" canary mode (miasma-train-p1). This is a live compromise, not the hypothetical branch-protection gap the summary describes.

How it works

An attacker with write access pushed unsigned commits (e.g. 3eab3ec, 5a70f7b–689f5b9) to unprotected auto-publish branches (next, alpha, master) on asyncapi/spec-json-schemas. These triggered AsyncAPI's legitimate GitHub Actions OIDC publish pipeline, so the malicious tarballs shipped to npm with valid SLSA provenance attestations — provenance proves where a build ran, not that it is safe. Maintainer npm accounts (fmvilas, derberg, asyncapi-bot) were never touched.

The malware uses a three-stage chain: a small require-time loader in the tarball → an IPFS downloader (sync.js, ~8.25 MB, generator CID QmQobZSp1…, specs CID Qmet4fhs…) → the full runtime. It beacons to C2 at 85.137.53.71:8080 / :8081, with failover over Nostr, IPFS, libp2p/DHT, and an Ethereum contract for address rotation. In the analyzed build, persistence and beaconing are on; propagation, credential harvesting, and AI-tool poisoning modules exist but are toggled off.

Preconditions / Affected

Any developer or CI job that installed the affected versions directly or transitively. Highest blast radius is @asyncapi/specs (~2.74M weekly downloads) because it is pulled transitively by @asyncapi/parser and CLI/generator trees — a project installing only @asyncapi/generator can still resolve specs@6.11.2 if its lockfile updated on July 14.

What to do

  • npm install --ignore-scripts does NOT protect you — the loader executes at require() time, not via lifecycle hooks.
  • Audit lockfiles for resolutions to @asyncapi/specs@6.11.2 or generator 3.3.1 / 0.7.1 / 1.1.1 dated July 14, 2026.
  • Search for the C2 indicator 85.137.53.71 on ports 8080/8081 in egress logs; the IPFS CIDs and commit hashes above are additional IOCs.
  • Treat tarball scanning as insufficient — most of the payload lives off-package in IPFS.

Caveats

The specs-campaign stage-3 payload was not decrypted or analyzed — analysis of runtime behavior comes from the generator build only. Download figures are all-version ecosystem reach, not confirmed compromise counts. Endor Labs assesses this as a canary probe and expects a follow-on wave with propagation, credential-harvest, and AI-tool (Claude, Cursor, Gemini, VSCode) toggles flipped on.

Organisations named here

  • AsyncAPI

Technologies named here

  • GitHub Actions
  • npm