AsyncAPI npm Supply Chain Compromise: GitHub Actions pull_request_target Exploit Deploys Miasma RAT to Packages with 2.9M Weekly Downloads

AsyncAPI npm Supply Chain Compromise (TL-2026-1320), also tracked as AsyncAPI npm supply chain compromise, is a critical-severity supply-chain compromise, first published 2026-07-14. It is attributed to M-RED-TEAM with low confidence, affects AsyncAPI Initiative @asyncapi/specs, maps to 29 MITRE ATT&CK techniques (T1008, T1020, T1027), and is covered by 9 detection rules and 22 indicators of compromise.

Key facts for TL-2026-1320

Threat ID
TL-2026-1320
Also known as
AsyncAPI npm supply chain compromise, Miasma RAT AsyncAPI campaign, M-RED-TEAM AsyncAPI backdoor
Severity
CRITICAL
Status
ACTIVE
Category
SUPPLY_CHAIN
First published
2026-07-14
Last reviewed
2026-07-14
Attribution
M-RED-TEAM
Attribution confidence
LOW
Motivation
FINANCIAL
Target sectors
technology, software-development, cloud-services, api-tooling, devops
Target regions
Global
Detection rules
9
Indicators of compromise
22

Malware and tooling in AsyncAPI npm Supply Chain Compromise

Malware and tooling: Miasma RAT (miasma-train-p1 build), 0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710

Attackers exploited a long-unpatched pull_request_target misconfiguration in the asyncapi/generator GitHub Actions workflow to exfiltrate a highly privileged npm publishing token belonging to the asyncapi-bot service account, then used it to publish five trojanized versions of four AsyncAPI npm packages (combined ~2.9M weekly downloads). The injected code runs on module import, downloads an encrypted multi-stage loader from IPFS, and deploys a remote-access trojan self-identified as "M-RED-TEAM v6.4" under the campaign tag miasma-train-p1, which beacons to an HTTP C2 server and maintains blockchain/decentralized fallback channels (Ethereum smart contract, Nostr relays, BitTorrent DHT, libp2p).

How AsyncAPI npm Supply Chain Compromise works

On 2026-07-14 at 05:08 UTC, an unknown threat actor opened 37 pull requests against the asyncapi/generator GitHub repository, the majority of which were decoy PRs proposing a fake charity donation page. One PR (#2155) contained JavaScript obfuscated behind roughly 1,000 bytes of leading whitespace that exploited the repository's pull_request_target GitHub Actions trigger. This trigger type runs workflows with access to base-repository secrets even when the workflow checks out attacker-controlled pull request code -- a known "pwn request" anti-pattern. A remediation PR (#2078/#2092) flagging this exact misconfiguration had been open and unmerged for 58-77 days (proposed 2026-04-29/05-17) at the time of the breach. The malicious workflow run completed at 05:16 UTC, exfiltrating a highly privileged Personal Access Token belonging to the asyncapi-bot service account to a dead-drop paste on rentry.co. Using the stolen token, the attacker pushed a malicious commit (3eab3ec9304aa26081358330491d3cfeb55cc245) directly to the next branch at 06:58 UTC, triggering the release workflow. The first three trojanized packages published at 07:10 UTC, with two additional compromised versions following between 07:51 and 08:28 UTC.

Five versions across four @asyncapi npm packages were backdoored: @asyncapi/specs (6.11.2 and 6.11.2-alpha.1, the highest-traffic package at ~2.7M weekly downloads alone), @asyncapi/generator (3.3.1), @asyncapi/generator-helpers (1.1.1), and @asyncapi/generator-components (0.7.1). Unlike npm supply-chain attacks that rely on postinstall lifecycle scripts, the malicious code was embedded directly inside runtime modules using three distinct injection techniques: whitespace obfuscation (roughly 880 padding spaces concealing payload inside legitimate function closures), direct inline injection prepended to index.js, and hex-variable obfuscation with base64-encoded string arrays via javascript-obfuscator with a custom base64 alphabet. This design ensures the payload fires on a simple require()/import call rather than only during npm install, evading defenses that only monitor lifecycle-script execution.

On import, the injected loader (Stage 1) spawns a detached Node.js child process (surviving parent termination, hidden from the user) that fetches an 8.2-8.25MB encrypted bundle (Stage 2) from IPFS (CIDs Qmet4fhsAaWMBUxNDfREHwgiyDeSWy4YSYs9wiKUW5jGyf for the specs payload and QmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9 for the generator-family payload), writing it to disk as sync.js under platform-specific per-user Node.js directories. The bundle is decrypted using ECDH + HKDF-SHA256 key derivation with AES-256-GCM (plus an ASCII rotation-reversal step), yielding Stage 3: a roughly 92,000-line modular RAT framework that self-identifies in runtime comments as "M-RED-TEAM v6.4" and internally as build target "miasma-train-p1". A hardcoded fallback master key ("rt-vault-master-key-32b-aaaaaaaa") was found in plaintext in the payload. The compiled payload build timestamp (2026-07-14 04:10 UTC) precedes the compromise by roughly three hours, indicating pre-staged tooling.

The deployed implant establishes persistence via systemd user service (Linux: ~/.config/systemd/user/miasma-monitor.service), shell rc-file injection with the marker "### Node Auto-Update Script ###" (macOS/Linux), and an HKCU Run-key registry entry (Windows), alongside a lock file (~/.config/.miasma/run/node.lock or ~/.config/miasma/runnode.lock) to prevent duplicate execution. It beacons via HTTP to 85.137.53.71:8080 approximately every 30 seconds using per-victim derived encryption keys and a custom header (X-Miasma-Spawn-Chain), with companion ports 8081 (upload/exfiltration) and 8091 (proxy management) on the same host (RIPE block 85.137.53.0/24, AS43641, Netherlands). Decentralized fallback channels include an Ethereum smart contract on mainnet (0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710), Nostr relays (wss://relay.damus.io, wss://relay.nostr.com/), BitTorrent DHT bootstrap nodes (router.bittorrent.com:6881, dht.transmissionbt.com:6881), plus IPFS, libp2p, and mDNS -- a seven-channel failover communications stack.

Active/enabled capabilities observed in the recovered build include a remote shell handler executing arbitrary commands via child_process.exec() (blacklisting only the literal string "killall"), file operations sandboxed to a /sim-fs path, system reconnaissance (PATH, HOME, USER, HOSTNAME), and payload update retrieval from Nostr/Ethereum sources. Analysts identified an extensive but largely DISABLED credential-harvesting module covering 300+ target file paths: AWS credentials (~/.aws/*), SSH/GPG keys, npm tokens (~/.npmrc), GitHub CLI config, Kubernetes/Docker registry auth, browser-saved passwords and cookies (Chrome, Brave, Firefox, Edge), macOS Keychain, cryptocurrency wallets (Bitcoin, Ethereum, Solana), AI-tool credentials (Claude/Anthropic, Cursor), and password managers (Bitwarden, 1Password, KeePassXC). Also present but toggled off: self-propagation modules targeting npm, PyPI, and Cargo; AI-developer-tool poisoning hooks (Claude, VS Code, Gemini, Cursor); a metamorphic self-modification/evasion engine; security-product sandbox-evasion checks (CrowdStrike, SentinelOne, Microsoft Defender, CarbonBlack, Cylance, Osquery, Tanium, Qualys); and a dead-man-switch that would wipe local directories if credential revocation were detected. The recovered configuration additionally contained misleading/contradictory flags (safeMode: true, actualPersist: false, canaryPercent: 5) that code analysis found did not match actual call-graph behavior.

Attribution is unresolved. The payload self-identifies as "M-RED-TEAM v6.4" and shares artifact naming, obfuscation tooling (javascript-obfuscator custom-alphabet config), and infrastructure-naming conventions (miasma-test-org, miasma-monitor.service, Miasma-tagged Nostr relays) with the open-source "Miasma" toolkit released publicly in June 2026, as well as dead-drop URL slug patterns ("elzotebo") matching a prior PR-flood campaign researchers term "prt-scan." However, researchers at Wiz explicitly declined definitive attribution, and JFrog/SafeDep analysis found the AsyncAPI deployment differs substantially from the June 2026 Red Hat-wave Miasma campaign in runtime (vanilla Node.js vs. Bun), payload staging location (persistent per-user directories vs. /tmp), crypto primitives (secp256k1+AES-256-GCM vs. RSA-4096+AES-256-CBC), and C2 design (persistent encrypted HTTP channel vs. GitHub-repo-based exfiltration), suggesting a copy-paste/rebrand of prior tooling by a distinct or evolved operator rather than a like-for-like reuse.

Aikido Security detected and disclosed the compromised packages on 2026-07-14. Remediation guidance from responders (Aikido, Wiz, JFrog, SafeDep, Upwind) converges on: pin/downgrade to the last-known-clean versions (@asyncapi/specs@6.11.1, @asyncapi/generator@3.3.0, @asyncapi/generator-helpers@1.1.0, @asyncapi/generator-components@0.7.0); remove the compromised versions from lockfiles/manifests; treat build-host and developer credentials as fully compromised and rotate npm tokens, GitHub tokens (including write tokens for both asyncapi/generator and the related asyncapi/spec-json-schemas repository, which was separately compromised), SSH/signing keys, AWS credentials, and CI/CD secrets from clean machines; hunt for the sync.js drop file and OS-specific persistence artifacts on any system that merely imported the affected modules (installation alone is sufficient exposure, since the payload fires on require/import, not only on npm install); and purge the compromised alpha tarball from CDN/package-registry backing storage. Longer-term hardening includes eliminating pull_request_target on workflows with external PR checkout, dependency allowlisting/SBOM generation, and enhanced build-environment/package-integrity monitoring.

MITRE ATT&CK techniques used in TL-2026-1320

Command and Control

T1008 Fallback Channels; T1071 Application Layer Protocol; T1102 Web Service; T1104 Multi-Stage Channels; T1105 Ingress Tool Transfer; T1205 Traffic Signaling; T1573 Encrypted Channel

Exfiltration

T1020 Automated Exfiltration; T1567 Exfiltration Over Web Service

Defense Evasion

T1027 Obfuscated Files or Information; T1140 Deobfuscate/Decode Files or Information; T1497 Virtualization/Sandbox Evasion

Execution

T1059 Command and Scripting Interpreter; T1106 Native API

Collection

T1074 Data Staged

Discovery

T1082 System Information Discovery; T1518 Software Discovery

Initial Access

T1195 Supply Chain Compromise; T1199 Trusted Relationship

Impact

T1485 Data Destruction

Credential Access

T1528 Steal Application Access Token; T1552 Unsecured Credentials; T1555 Credentials from Password Stores

Persistence

T1543 Create or Modify System Process; T1546 Event Triggered Execution; T1547 Boot or Logon Autostart Execution

Resource Development

T1584 Compromise Infrastructure; T1587 Develop Capabilities

defense-impairment

T1685 Disable or Modify Tools

Affected products and versions in AsyncAPI npm Supply Chain Compromise

  • AsyncAPI Initiative — @asyncapi/specs
    Vulnerable versions: 6.11.2; 6.11.2-alpha.1
    Fixed in: 6.11.1 (downgrade/pin)
  • AsyncAPI Initiative — @asyncapi/generator
    Vulnerable versions: 3.3.1
    Fixed in: 3.3.0 (downgrade/pin)
  • AsyncAPI Initiative — @asyncapi/generator-helpers
    Vulnerable versions: 1.1.1
    Fixed in: 1.1.0 (downgrade/pin)
  • AsyncAPI Initiative — @asyncapi/generator-components
    Vulnerable versions: 0.7.1
    Fixed in: 0.7.0 (downgrade/pin)

Remediation for AsyncAPI npm Supply Chain Compromise

Patches

  • No CVE assigned; remediation is version pinning to the pre-compromise releases (6.11.1 / 3.3.0 / 1.1.0 / 0.7.0), not a vendor patch

Immediate actions

  • Pin/downgrade @asyncapi/specs to 6.11.1, @asyncapi/generator to 3.3.0, @asyncapi/generator-helpers to 1.1.0, and @asyncapi/generator-components to 0.7.0 in all manifests and lockfiles
  • Remove all trojanized versions (@asyncapi/specs 6.11.2 and 6.11.2-alpha.1, @asyncapi/generator 3.3.1, @asyncapi/generator-helpers 1.1.1, @asyncapi/generator-components 0.7.1) from package caches, CI mirrors, and CDN/registry backing storage
  • Hunt every system that installed OR merely imported the affected modules for sync.js in per-user NodeJS directories (~/.local/share/NodeJS/, ~/Library/Application Support/NodeJS/, %LOCALAPPDATA%\NodeJS\)
  • Hunt for persistence artifacts: ~/.config/systemd/user/miasma-monitor.service, shell rc-file entries marked '### Node Auto-Update Script ###', HKCU\Software\Microsoft\Windows\CurrentVersion\Run registry entries, and lock files at ~/.config/.miasma/run/node.lock
  • Block outbound network traffic to 85.137.53.71/32 (ports 8080/8081/8091) and the broader 85.137.53.0/24 range at the perimeter and on EDR
  • Treat all npm publish tokens, GitHub PATs (especially service-account tokens like asyncapi-bot), SSH keys, AWS credentials, and CI/CD secrets on affected build hosts as compromised and rotate from a clean, isolated machine
  • Rotate write tokens for both asyncapi/generator and asyncapi/spec-json-schemas repositories

Workarounds

  • Vendor/mirror a known-clean copy of the AsyncAPI packages internally until upstream trust is re-established
  • Add the compromised versions to an internal npm audit/deny-list to block reinstallation

Longer-term hardening

  • Eliminate pull_request_target triggers on workflows that check out untrusted external pull-request code; use pull_request with restricted read-only permissions instead, or explicitly checkout the base ref
  • Require workflow secret access to be scoped/reviewed and gated by required approval for first-time or external contributors
  • Deploy dependency allowlisting, SBOM generation, and package-integrity/provenance verification (e.g., npm provenance, Sigstore) for all published artifacts
  • Implement CI/CD build-environment monitoring for unexpected outbound network connections and detached child-process spawning during test/build steps
  • Monitor npm packages for post-publish diffing against source-controlled commits to catch token-based unauthorized publishes

Weaknesses (CWE) in AsyncAPI npm Supply Chain Compromise

CWE-1357, CWE-506, CWE-798, CWE-829

Timeline of AsyncAPI npm Supply Chain Compromise

  • A contributor identifies the pull_request_target GitHub Actions misconfiguration in asyncapi/generator and opens remediation PR #2078.
  • A follow-up security fix (PR #2092) is proposed to close the pull_request_target secrets-exposure gap; it remains unmerged.
  • Researchers publish coordinated remediation guidance: downgrade to pre-compromise versions, rotate all CI/CD and developer credentials, and hunt for sync.js and related persistence artifacts.
  • Aikido, Wiz, JFrog, SafeDep, and Upwind publish independent technical analyses of the compromise and the Miasma RAT payload.
  • Aikido Security analysts detect the trojanized releases via automated malicious-package scanning and begin disclosure.
  • Between 07:51 and 08:28 UTC, two additional compromised versions (@asyncapi/generator-components 0.7.1 and @asyncapi/specs 6.11.2-alpha.1) are published.
  • At 07:10 UTC the first three trojanized packages (@asyncapi/specs, @asyncapi/generator, @asyncapi/generator-helpers) are published to npm.
  • At 06:58 UTC the attacker uses the stolen token to push malicious commit 3eab3ec9304aa26081358330491d3cfeb55cc245 directly to the next branch, triggering the release workflow.
  • At 05:16 UTC the malicious pull_request_target workflow run completes, exfiltrating the asyncapi-bot npm publish token to a dead-drop paste hosted on rentry.co.
  • At 05:08 UTC the attacker opens 37 pull requests against asyncapi/generator; the majority are decoy PRs proposing a fake charity donation page, while PR #2155 contains an obfuscated JavaScript payload.

Sources cited for AsyncAPI npm Supply Chain Compromise

Threats related to AsyncAPI npm Supply Chain Compromise

Detection coverage for TL-2026-1320

As of 2026-07-14, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1320 across Splunk SPL, Microsoft KQL and Sigma, covering 22 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.

Community OSINT corroboration for TL-2026-1320

1 of this threat's indicators have also been reported by the open-source security community. Community sightings are unverified and are kept separate from Threadlinqs' curated indicators. Indicator values, reporters and campaign linkage are available to authenticated Red-tier users.

Further reading

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Latest Threats