# AsyncAPI npm Supply Chain Compromise: Import-Time Payload Delivery via Miasma Loader

> On July 14, 2026, an attacker abused a misconfigured GitHub Actions workflow to gain push access to AsyncAPI repositories and let the project's own trusted-publishing CI/CD pipeline republish five malicious versions across four npm packages (@asyncapi/specs, @asyncapi/generator, @asyncapi/generator-components, @asyncapi/generator-helpers). The poisoned packages carry a modular loader that fires at import/require time — not via npm lifecycle scripts — bypassing the common `npm install --ignore-scripts` mitigation, and download the Miasma RAT/botnet framework from IPFS.

- **Published:** 2026-07-15T00:00:00Z
- **Last reviewed:** 2026-09-08T02:33:19.424Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-1387
- **Card image:** https://intel.threadlinqs.com/og/threat/threat-intel-asyncapi-npm-miasma-import-loader-tl-2026-1387.webp?v=94ba7e61 (Threadlinqs threat intel: Miasma RAT in AsyncAPI npm Packages: Detection & IOCs (TL-2026-1387) — Critical severity, 52 IOCs, 9 detection rules.)
- **ID:** TL-2026-1387
- **Severity:** CRITICAL (CVSS 9.8)
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Detections:** 9 (1 shown free below) · **IOCs:** 52 (3 shown free below)

## Description

On July 14, 2026, attackers compromised the AsyncAPI npm publishing pipeline through legitimate CI/CD abuse rather than direct npm token theft. A decoy campaign of roughly 37 pull requests (most adding a fake charity donation page to camouflage the real attack) was opened against the asyncapi/generator repository; one PR exploited a misconfigured GitHub Actions workflow using `pull_request_target` with untrusted head-commit checkout (in `manual-netlify-preview.yml`), which carried a broadly privileged GITHUB_TOKEN and repository secret access. The attacker used this to obtain push access to the `next` branch of asyncapi/generator and the `master` branch of asyncapi/spec-json-schemas, then pushed malicious commits directly. This triggered the repositories' own legitimate release automation — `release-with-changesets.yml` fired within 12 seconds of the malicious push to asyncapi/generator, and `if-nodejs-release.yml` fired on a commit carrying a `fix:`/`feat:` prefix for spec-json-schemas — causing npm's GitHub Actions OIDC trusted-publisher integration to sign and publish the poisoned tarballs with valid SLSA/npm provenance attestations. Provenance verification therefore did not catch the attack: it only certifies that the authorized workflow produced the artifact, not that the triggering commit was legitimate.

Five malicious versions were published between 06:58 and 08:30 UTC on July 14, 2026: @asyncapi/generator@3.3.1, @asyncapi/generator-components@0.7.1, @asyncapi/generator-helpers@1.1.1, @asyncapi/specs@6.11.2-alpha.1, and @asyncapi/specs@6.11.2 (stable). Microsoft observed the first downstream fetch of the poisoned @asyncapi/specs tarball into a Yarn cache at 08:49:22 UTC, roughly 40 minutes after publication, confirming active exploitation in the wild within the exposure window (07:10-11:18 UTC). The combined weekly download footprint of the four affected packages exceeds 2.9 million, with @asyncapi/specs alone accounting for roughly 2.7 million weekly downloads, making this one of the highest-blast-radius npm compromises of 2026.

Each injected package carries an import-time dropper rather than an install-time lifecycle hook (no preinstall/install/postinstall entries were declared in package.json), specifically to defeat `npm install --ignore-scripts` and hook-focused SCA/security scanners. The generator-family packages used raw obfuscated CommonJS padded with roughly 1,000 leading spaces per line to hide the payload in diffs; the specs package used an ESM/TypeScript-compiled obfuscator.io build with distinct decoder functions. When the poisoned module is `require()`d or imported during normal application/CI/build usage, the loader spawns a detached, stdio-ignored `node` child process (`spawn('node', [payloadPath], {detached: true, stdio: 'ignore'})`) that reconstructs a transport routine from an IPFS-hosted `sync.js` stager. That stager fetches an approximately 3.08 MB Node.js bundle from IPFS, decrypts it using HKDF-SHA256 (salt/info string `rt-file-key-material-v1` / `rt-file-key`) to derive AES-256-GCM keys plus an auxiliary ROT-style substitution cipher (shift=4, delta=90 across ASCII 33-126), and executes the decrypted payload: the Miasma RAT/botnet framework (internally versioned M-RED-TEAM v6.4 / Miasma RAT v3, campaign tags `miasma-train-p1` and `miasma-test-org`).

Miasma is a modular, multi-channel botnet framework comprising roughly 744 modules and a 12-command tasking protocol (Propagate, CollectData, UpdateMutationSeed, UpdatePayload, ManualSelfDestruct, BatchDispatch, FileList/FileGet/FilePut/FileDelete, ShellExec, UpdateBeaconInterval) with only `killall` blacklisted from shell execution, giving the operator near-arbitrary command execution on infected hosts. It supports six C2 channels for resilience against takedown: HTTP REST to a hardcoded IP, Nostr relays, IPFS, Ethereum blockchain (via a smart contract and a public RPC endpoint), BitTorrent DHT, and libp2p GossipSub mesh. The observed build shipped with credential harvesting (130+ target types spanning SSH keys, npmrc, AWS/Azure/GCP credentials, GitHub tokens/CLI config, browser-saved passwords, macOS Keychain, kubeconfig), LAN lateral-movement/subnet-scanning modules, an AI-coding-assistant poisoning module (targeting Claude Code, GitHub Copilot, Cursor sessions), a metamorphic/polymorphic re-obfuscation engine, and cross-ecosystem propagation stubs for PyPI, RubyGems, and Cargo -- but the credential harvesting, reconnaissance, and propagation capabilities were toggled disabled (`recon:false`, `propagate:false`) in this observed campaign build, indicating either a staged rollout, a testing/demonstration deployment, or throttled activation pending further operational decisions by the operator.

Persistence is established via platform-specific mechanisms: a Windows HKCU Run registry key (`miasma-monitor`), a Linux systemd user unit (`miasma-monitor.service`) plus crontab entries, a launchd agent on macOS, and shell RC file injection (.zshrc/.bashrc/.bash_profile) as a cross-platform fallback. The dropped stager and lock files masquerade under legitimate-looking `NodeJS` application-data directory names on all three major OS families to blend in with genuine Node.js installation artifacts.

Microsoft, Socket.dev, StepSecurity, Wiz, SafeDep, OX Security, Rescana, and The Hacker News independently corroborated the core technical findings (import-time execution, IPFS-hosted payload, hardcoded C2 IP, and the CI/CD trusted-publishing abuse mechanism), giving high confidence in the reported IOCs and mechanics. All five malicious versions have since been unpublished from the npm registry, with dist-tags reset to known-clean releases (@asyncapi/specs@6.11.1, @asyncapi/generator@3.3.0, @asyncapi/generator-helpers@1.1.0, @asyncapi/generator-components@1.0.0). No threat-actor attribution has been established; the poisoned commits carried a generic Git author identity ("Your Name <you@example.com>"), consistent with an opportunistic or as-yet-unidentified actor rather than a named APT group.

## MITRE ATT&CK

- T1584 Compromise Infrastructure
- T1195 Supply Chain Compromise
- T1195.001 Compromise Software Dependencies and Development Tools
- T1195.002 Compromise Software Supply Chain
- T1199 Trusted Relationship
- T1059 Command and Scripting Interpreter
- T1059.007 JavaScript
- T1129 Shared Modules
- T1547 Boot or Logon Autostart Execution
- T1547.001 Registry Run Keys / Startup Folder
- T1547.006 Kernel Modules and Extensions
- T1546.004 Unix Shell Configuration Modification
- T1053.003 Cron
- T1036 Masquerading
- T1036.005 Match Legitimate Resource Name or Location
- T1140 Deobfuscate/Decode Files or Information
- T1027 Obfuscated Files or Information
- T1070 Indicator Removal
- T1685 Disable or Modify Tools
- T1555 Credentials from Password Stores
- T1552 Unsecured Credentials
- T1528 Steal Application Access Token
- T1056.004 Credential API Hooking
- T1082 System Information Discovery
- T1046 Network Service Discovery
- T1570 Lateral Tool Transfer
- T1005 Data from Local System
- T1213 Data from Information Repositories
- T1071 Application Layer Protocol
- T1071.001 Web Protocols
- T1105 Ingress Tool Transfer
- T1572 Protocol Tunneling
- T1104 Multi-Stage Channels
- T1008 Fallback Channels
- T1041 Exfiltration Over C2 Channel
- T1565 Data Manipulation
- T1190 Exploit Public-Facing Application
- T1078 Valid Accounts
- T1543.003 Create or Modify System Process
- T1027.001 Obfuscated Files or Information

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**Miasma Multi-Channel C2 Beacon — Hardcoded IP / IPFS / Nostr / DHT / Ethereum RPC** (`TL-2026-1387-SPL-003`)

Detects outbound connections from a Node.js process to Miasma's known C2 infrastructure — the hardcoded IP 85.137.53.71 on ports 8080/8081/8091, public IPFS gateways, Nostr relay WebSocket endpoints, BitTorrent DHT bootstrap nodes, or public Ethereum RPC endpoints — correlated with recent npm/yarn install activity, reflecting the framework's six-channel C2 resilience design.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1071.001, T1104, T1008, T1572, T1105
- **Data sources:** network_flow_stream, firewall_traffic_logs, device_network_events, dns_logs
- **Severity:** critical
- **Confidence:** high

### Splunk SPL

```spl
index=network sourcetype="stream:tcp" OR sourcetype="pan:traffic"
| eval process_hint=if(match(app, "(?i)node") OR match(process_name, "(?i)node"), 1, 1)
| where (dest_ip="85.137.53.71" AND dest_port IN (8080,8081,8091))
   OR match(dest_host, "(?i)(ipfs\.io|dweb\.link|cloudflare-ipfs\.com)")
   OR match(dest_host, "(?i)relay\.damus\.io|relay\.nostr\.com")
   OR match(dest_host, "(?i)router\.bittorrent\.com|dht\.transmissionbt\.com")
   OR match(dest_host, "(?i)ethereum-rpc\.publicnode\.com")
| join type=left host [ search index=os_logs sourcetype="cmdline" ("npm install" OR "npm ci" OR "yarn install") | eval install_time=_time | table host install_time ]
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, host, dest_ip, dest_host, dest_port, install_time
| where count > 0
```

### Microsoft KQL

```kql
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where InitiatingProcessFileName in~ ("node.exe", "node")
| where (RemoteIP == "85.137.53.71" and RemotePort in (8080, 8081, 8091))
   or RemoteUrl has_any ("ipfs.io", "dweb.link", "cloudflare-ipfs.com", "relay.damus.io", "relay.nostr.com", "router.bittorrent.com", "dht.transmissionbt.com", "ethereum-rpc.publicnode.com")
| project Timestamp, DeviceId, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemoteUrl, RemotePort, RemoteUrl
```

### Sigma

```yaml
title: Miasma RAT Multi-Channel C2 Beacon (Hardcoded IP, IPFS, Nostr, DHT, Ethereum RPC)
id: 6f2a1e0c-4b3d-4a6f-9c1e-1a2b3c4d5e03
status: experimental
description: Detects outbound connections from a node process to Miasma's known multi-channel C2 infrastructure, including the hardcoded IP 85.137.53.71 and IPFS/Nostr/DHT/Ethereum RPC fallback channels.
references:
    - https://www.wiz.io/blog/m-red-team-asyncapi-supply-chain-compromise-via-github-actions
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-07-15
tags:
    - attack.command_and_control
    - attack.t1071.001
    - attack.t1104
    - attack.t1008
    - attack.t1572
    - attack.t1105
    - attack.tool.miasma_rat
logsource:
    category: network_connection
    product: linux
detection:
    selection_ip:
        Initiated: true
        DestinationIp: '85.137.53.71'
        DestinationPort:
            - 8080
            - 8081
            - 8091
    selection_domains:
        Initiated: true
        DestinationHostname|contains:
            - 'ipfs.io'
            - 'dweb.link'
            - 'relay.damus.io'
            - 'relay.nostr.com'
            - 'router.bittorrent.com'
            - 'dht.transmissionbt.com'
            - 'ethereum-rpc.publicnode.com'
    condition: selection_ip or selection_domains
falsepositives:
    - Legitimate developer/CI use of public IPFS gateways or Ethereum public RPC endpoints for unrelated projects
level: high
```

**Known false positives:**

- Legitimate build/CI processes that intentionally use public IPFS gateways or Ethereum public RPC nodes for unrelated blockchain/web3 tooling

**Tuning notes:** The hardcoded-IP leg (85.137.53.71) should be treated as unconditionally high-confidence; the IPFS/Nostr/DHT/Ethereum legs should be scoped to build/CI network zones and correlated with a recent npm/yarn install to suppress unrelated web3-developer noise.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- Import-Time Node Require Trigger with Immediate Detached Spawn (locked: unlock with TL Creds)
- Miasma NodeJS-Masquerading Directory Write ([indicator] / node.lock) (locked: unlock with TL Creds)
- Miasma Tasking-Protocol ShellExec / File Operations from Beaconing Host (locked: unlock with TL Creds)
- Sigma: Poisoned npm Package Import-Time Node Spawn Chain (locked: unlock with TL Creds)
- Sigma: HKCU Run Key or Autostart Entry Referencing 'miasma-monitor' (locked: unlock with TL Creds)
- Sigma: node --ignore-scripts Install Followed by Outbound C2-Pattern Egress (locked: unlock with TL Creds)
- Miasma Import-Time Loader — Detached Node Child Process Spawn (locked: unlock with TL Creds)
- Miasma RAT Persistence — Run Key / systemd Unit / Cron / Shell RC Injection (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sample indicators (3 of 52)

Defanged, TLP:CLEAR.

- IP address: `85.137.53[.]71`
- Domain: `router[.]bittorrent[.]com`
- URL: `hxxps://ipfs[.]io`

Full set of 52 indicators unlocks with TL Creds: https://threadlinqs.com/tl-creds

## Sources

- [Unpacking AsyncAPI npm supply chain compromise: 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/)
- [Compromised npm Packages in the AsyncAPI Namespace Deliver Miasma RAT](https://socket.dev/blog/asyncapi-supply-chain-attack)
- [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)
- [Active Exploitation Alert: AsyncAPI npm Supply Chain Attack Delivers Multi-Stage Miasma Botnet via Compromised GitHub Actions](https://www.rescana.com/post/active-exploitation-alert-asyncapi-npm-supply-chain-attack-delivers-multi-stage-miasma-botnet-via-compromised-github-act)
- [AsyncAPI Packages Compromised with Miasma RAT](https://safedep.io/asyncapi-generator-supply-chain-attack-miasma-rat/)
- [Compromised AsyncAPI npm Packages Deliver Multi-Stage Botnet Malware](https://thehackernews.com/2026/07/compromised-asyncapi-npm-packages.html)
- [AsyncAPI npm organization compromised, 2M weekly downloads affected](https://www.ox.security/blog/asyncapi-npm-organization-compromised-2m-weekly-downloads-affected/)
- [Four AsyncAPI npm packages carry Miasma botnet loader](https://www.developer-tech.com/news/four-asyncapi-npm-packages-miasma-botnet-loader/)
- [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)
- [Security advisory: malicious AsyncAPI package versions published (Miasma RAT)](https://github.com/Kong/insomnia/issues/10252)
- [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)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-1387
