Threat reportSupply ChainTL-2026-1360
AsyncAPI npm Supply Chain Attack: Pwn-Request GitHub Actions Compromise Deploys Miasma Tasking Framework
An attacker exploited a 'pwn request' flaw in a misconfigured pull_request_target GitHub Actions workflow (manual-netlify-preview.yml) to steal a privileged asyncapi-bot Personal Access Token, then used the AsyncAPI project's own legitimate release pipelines and npm OIDC trusted-publisher integration to push five malicious @asyncapi package versions carrying valid SLSA provenance.
Key facts for AsyncAPI Miasma npm compromise
| Identifiers | TL-2026-1360 |
|---|---|
| Also known as | Miasma tasking framework campaign, AsyncAPI pwn-request supply chain attack |
| Severity | CRITICAL |
| CVSS | 9.8 |
| Exploitation status | Exploited in the wild |
| Affected products | AsyncAPI Initiative @asyncapi/generator (npm); AsyncAPI Initiative @asyncapi/generator-helpers (npm); AsyncAPI Initiative @asyncapi/generator-components (npm); AsyncAPI Initiative @asyncapi/specs (npm) |
| Weaknesses (CWE) | CWE-829, CWE-494, CWE-506, CWE-522, CWE-269, CWE-287, CWE-913, CWE-94, CWE-200 |
| Attribution | M-RED-TEAM (low confidence) |
| Malware | Miasma |
| Tools | 0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710 |
| MITRE ATT&CK techniques | T1005 Data from Local System, T1016 System Network Configuration Discovery, T1027 Obfuscated Files or Information, T1027.002 Obfuscated Files or Information, T1036.005 Match Legitimate Resource Name or Location, T1041 Exfiltration Over C2 Channel, T1046 Network Service Discovery, T1053.003 Cron, T1059.004 Command and Scripting Interpreter, T1059.007 JavaScript, T1071.001 Web Protocols, T1082 System Information Discovery and 30 more in the attack flow |
| Motivation | FINANCIAL |
| Target sectors | technology, software-development, cloud-services, any-npm-consumer |
| Target regions | Global |
| Detection rules | 9 (1 shown free) |
| Sources | 8 cited sources |
Detection coverage for AsyncAPI Miasma npm compromise
As of 2026-10-29, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1360 across Splunk SPL, Microsoft KQL and Sigma, covering 54 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.
Free detection: Node.js Spawns Hidden PowerShell Child Process (Miasma require()-Trigger)
Detects the exploitation trigger for the Miasma dropper: a hidden, stdio-suppressed PowerShell process spawned by node.exe the moment a poisoned @asyncapi module is require()'d during build/CI, not at npm install time.
- Languages: Splunk SPL, Microsoft KQL, Sigma
- ATT&CK: T1059.007, T1204.002, T1027
- Data sources: sysmon, windows_security, microsoft_defender_for_endpoint
- Severity: critical
- Confidence: high
Splunk SPL
index=endpoint sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
| where match(ParentImage, "(?i)\\\\node\.exe$") AND match(Image, "(?i)\\\\powershell\.exe$")
| where match(CommandLine, "(?i)-windowstyle\s+hidden") AND match(CommandLine, "(?i)-noprofile")
| eval risk_reason="node.exe spawned hidden PowerShell child during require()"
| table _time, ComputerName, User, ParentImage, Image, CommandLine, ProcessGuid, risk_reason
| sort -_timeMicrosoft KQL
DeviceProcessEvents
| where Timestamp > ago(24h)
| where InitiatingProcessFileName =~ "node.exe"
| where FileName =~ "powershell.exe"
| where ProcessCommandLine has "-WindowStyle" and ProcessCommandLine has "Hidden"
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine, InitiatingProcessId, ProcessIdSigma
title: Suspicious Hidden PowerShell Child Process Spawned by Node.js (Miasma Dropper Trigger)
id: 7c2a1e10-4b3d-4a2f-9e5c-1a2b3c4d5e01
status: experimental
description: Detects a hidden, stdio-suppressed PowerShell process spawned by node.exe, matching the Miasma/AsyncAPI supply-chain dropper's require()-time Stage 1 trigger
references:
- https://socket.dev/blog/asyncapi-supply-chain-attack
- 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.execution
- attack.t1059.007
- attack.t1204.002
- attack.tool.miasma
logsource:
product: windows
category: process_creation
detection:
selection:
ParentImage|endswith: '\node.exe'
Image|endswith: '\powershell.exe'
CommandLine|contains|all:
- '-WindowStyle'
- 'Hidden'
condition: selection
falsepositives:
- Legitimate Node.js build tooling that shells out to PowerShell for signing/packaging scripts
level: highKnown false positives:
- Legitimate CI/build scripts that intentionally launch hidden PowerShell helpers from Node.js tooling
Tuning notes: Scope to CI runner and developer-workstation asset groups first to reduce noise from unrelated automation; add an allowlist for known internal build scripts once validated.
- Registry Run Key Persistence Under Generic Monitor/Sync Name (Miasma-style) · unlock with TL Creds
- systemd User Service Created with Restart=always by Non-Package-Manager Process · unlock with TL Creds
- Anti-Analysis Security-Tool Enumeration Preceding Credential-Store Access · unlock with TL Creds
- Placeholder-Identity Commit Directly Preceding OIDC-Triggered npm Publish · unlock with TL Creds
- Multi-Channel Beacon Pattern: HTTP + Nostr/IPFS/DHT Fallback with Jitter · unlock with TL Creds
- LAN Subnet Scan / mDNS Discovery Originating from Node.js Process · unlock with TL Creds
- Poisoned npm Package require() Triggers Outbound IPFS Fetch · unlock with TL Creds
- Malicious @asyncapi Package Version Resolved in Build/Install · unlock with TL Creds
Indicators of compromise for AsyncAPI Miasma npm compromise
As of 2026-10-29, Threadlinqs Intelligence tracks 54 indicators of compromise for TL-2026-1360.
Sample indicators (3 of 54)
- IP address:
85.137.53[.]71 - Domain:
router[.]bittorrent[.]com - File hash:
34014776d3d3ff11bc4439b02fd7ac0f02a887eb3a052eeafff236e2f6db8ad1
Defanged, TLP:CLEAR. Full set of 54 indicators: unlock with TL Creds.
Community OSINT corroboration for AsyncAPI Miasma npm compromise
5 of this threat's indicators have also been reported by the open-source security community, which observed at least one of them before this report was published. 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.
How AsyncAPI Miasma npm compromise works
The packages deployed a three-stage dropper culminating in a 744-module, 92,000-line Miasma-family tasking framework with six independent C2 channels (HTTP, Nostr, IPFS, BitTorrent DHT, libp2p GossipSub, Ethereum smart contract), credential/wallet theft, AI coding-assistant poisoning, LAN worm propagation, and a dead man's switch that wipes local directories if the stolen token is revoked.
On 2026-04-29 a researcher reported a pull_request_target misconfiguration in asyncapi/generator's manual-netlify-preview.yml workflow; a proposed fix on 2026-05-17 was never merged. On 2026-07-14 an attacker weaponized the flaw: they opened 37 pull requests against asyncapi/generator, almost all a noisy decoy adding a fake charity donation page, while PR #2155 hid obfuscated JavaScript after roughly 1,000 bytes of whitespace. Because manual-netlify-preview.yml triggered on pull_request_target but checked out attacker-controlled PR code, the workflow executed with base-repository secrets and exfiltrated a highly privileged Personal Access Token belonging to the asyncapi-bot service account.
At 06:58 UTC the attacker pushed commit 3eab3ec9304aa26081358330491d3cfeb55cc245 to the next branch under the placeholder git identity "Your Name <you@example.com>" (GitHub API resolved the email as invalid, consistent with a compromised push credential rather than a legitimate contributor). This automatically triggered the project's own release-with-changesets.yml workflow via npm's GitHub OIDC trusted-publisher integration at 07:10 UTC, publishing @asyncapi/generator@3.3.1, @asyncapi/generator-helpers@1.1.1, and @asyncapi/generator-components@0.7.1 with valid SLSA provenance attestations -- attestations that prove only that the authorized workflow produced the artifact, not that the triggering commit was legitimate. Between 07:51-07:56 UTC the same attacker pushed commit 36269ce81837 to the master branch of asyncapi/spec-json-schemas, causing the if-nodejs-release.yml workflow to publish @asyncapi/specs@6.11.2-alpha.1 (08:06 UTC) and @asyncapi/specs@6.11.2 (08:30 UTC). Combined, the four packages see roughly 2-3 million weekly downloads.
Unlike prior npm supply-chain attacks that relied on postinstall lifecycle hooks (now restricted by npm v12), the dropper was injected directly into legitimate source files (apps/generator/lib/templates/config/validator.js, packages/helpers/src/utils.js, packages/components/src/utils/ErrorHandling.js, and the specs package's compiled ESM index.js) and fires the moment the module is require()'d during normal build or CI use -- not at npm install time. Stage 1 spawns a detached, stdio-suppressed Node.js child process (windowsHide:true) that downloads an encrypted Stage 2 blob from IPFS (CID QmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9 for the generator packages, Qmet4fhsAaWMBUxNDfREHwgiyDeSWy4YSYs9wiKUW5jGyf for specs) and drops it to an OS-specific hidden path (sync.js under NodeJS support directories on Windows/macOS/Linux). Stage 2 decrypts an 8.25MB bundle using AES-256-GCM with HKDF-SHA256 key derivation (labels rt-vault-master-key-32b-aaaaaaaa, rt-file-key-material-v1, rt-baked-key) to yield Stage 3: a 3.08-3.09MB, ~92,000-line JavaScript tasking framework that self-identifies in code as both "miasma-train-p1" and "M-RED-TEAM v6.4".
The framework implements 744 bundled modules and 12+ command handlers (file listing/retrieval/write, shell execution, payload update, beacon-interval update, credential ciphering, node signing) across six independent C2 channels: primary HTTP/REST beaconing to 85.137.53.71:8080 (/api/v1/beacon, /api/v1/file-result) with dedicated upload (8081) and proxy-management (8091) ports, Nostr relay fallback (wss://relay.damus.io, wss://relay.nostr.com), IPFS, BitTorrent DHT (router.bittorrent.com, router.utorrent.com, dht.transmissionbt.com), libp2p GossipSub P2P mesh, and an Ethereum smart contract (0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710) as a blockchain dead-drop fallback. Credential-theft targets npm/GitHub/PyPI tokens, SSH keys, browser-stored passwords, macOS Keychain, and AWS/Azure/GCP cloud credentials. A dedicated ai-tool-poisoner.js module targets Claude Code, GitHub Copilot, and Cursor configuration, meaning any AI coding session on an affected workstation must be treated as compromised. LAN lateral movement uses subnet scanning and mDNS discovery; a metamorphic mutation engine supports polymorphic re-propagation, though baked configuration toggles for PyPI/RubyGems/Cargo/cryptocurrency propagation modules were observed disabled despite the code being present. Persistence is established via a systemd user service (~/.config/systemd/user/miasma-monitor.service, Restart=always), crontab, macOS launchd, and Windows Registry Run keys. Anti-analysis logic terminates on detected sandboxes/VMs, on hosts with a Russian system locale, or where CrowdStrike, SentinelOne, Microsoft Defender, CarbonBlack, Cylance, Osquery, Tanium, or Qualys are present. A dead man's switch continuously monitors validity of the stolen token and triggers a local directory wipe if it is revoked.
All five malicious versions were unpublished from npm between 11:12-11:18 UTC on 2026-07-14 (exposure windows of roughly 2h48m-4h3m); the latest dist-tags now resolve to clean versions (generator@3.3.0, generator-helpers@1.1.0, generator-components@1.0.0, specs@6.11.1). Researchers note code-level obfuscation overlaps and shared naming conventions with the prior Red Hat Cloud Services npm 'Miasma: The Spreading Blight' campaign (itself built on leaked/open-sourced Shai-Hulud code) and the 'prt-scan' Rentry dead-drop campaign, but caution that no definitive attribution has been established -- one analysis argues the 'Miasma' strings may be a deliberate false-flag to mislead responders. Regardless of branding, defenders should treat any endpoint or CI runner that imported or executed one of the five affected package versions as compromised: rotate npm/GitHub/SSH/cloud credentials, remove dropper artifacts and orphaned processes, audit CI egress logs for connections to ipfs.io, 85.137.53.71, DHT bootstrap nodes, or Nostr relays, and treat AI coding-assistant sessions on affected hosts as untrusted.
MITRE ATT&CK techniques by tactic:
Collection
T1005 Data from Local System; T1560 Archive Collected Data
Discovery
T1016 System Network Configuration Discovery; T1046 Network Service Discovery; T1082 System Information Discovery; T1518.001 Security Software Discovery
Defense Evasion
T1027 Obfuscated Files or Information; T1027.002 Obfuscated Files or Information; T1036.005 Match Legitimate Resource Name or Location; T1140 Deobfuscate/Decode Files or Information; T1497.001 System Checks; T1564.001 Hidden Files and Directories
Exfiltration
T1041 Exfiltration Over C2 Channel
Persistence
T1053.003 Cron; T1543.001 Launch Agent; T1543.002 Systemd Service; T1546.004 Event Triggered Execution; T1547.001 Registry Run Keys / Startup Folder
Execution
T1059.004 Command and Scripting Interpreter; T1059.007 JavaScript; T1204.002 Malicious File
Command and Control
T1071.001 Web Protocols; T1090 Proxy; T1095 Non-Application Layer Protocol; T1102.002 Bidirectional Communication; T1102.003 Web Service; T1105 Ingress Tool Transfer; T1571 Non-Standard Port
Initial Access
T1195.001 Supply Chain Compromise; T1195.002 Compromise Software Supply Chain; T1199 Trusted Relationship
Impact
Credential Access
T1528 Steal Application Access Token; T1552.001 Credentials In Files; T1552.004 Unsecured Credentials; T1552.005 Cloud Instance Metadata API; T1555.001 Keychain; T1555.003 Credentials from Web Browsers
Lateral Movement
Resource Development
T1583.004 Server; T1588.001 Malware
defense-impairment
Remediation for AsyncAPI Miasma npm compromise
Patches
- Upgrade to clean dist-tag versions: @asyncapi/generator@3.3.0, @asyncapi/generator-helpers@1.1.0, @asyncapi/generator-components@1.0.0, @asyncapi/specs@6.11.1
- Merge the previously-proposed (2026-05-17) fix for the manual-netlify-preview.yml pull_request_target misconfiguration
Immediate actions
- Pin/lockfile-freeze dependencies below the malicious versions and regenerate lock files to prevent resolution of @asyncapi/generator@3.3.1, @asyncapi/generator-helpers@1.1.1, @asyncapi/generator-components@0.7.1, @asyncapi/specs@6.11.2, @asyncapi/specs@6.11.2-alpha.1
- Remove dropper artifacts from documented drop paths (sync.js under NodeJS support directories) and kill orphaned detached Node.js processes
- Block/monitor outbound connections to 85.137.53.71, ipfs.io payload CIDs, listed Nostr relays, and BitTorrent DHT bootstrap nodes at network egress
- Treat any CI runner or workstation that require()'d an affected version during build/CI as compromised, not just those that ran npm install
Workarounds
- Temporarily vendor or mirror AsyncAPI generator toolchain from a known-clean commit/tag until upstream workflow hardening is confirmed
Longer-term hardening
- Audit all pull_request_target-triggered GitHub Actions workflows for checkout-of-untrusted-code (pwn request) patterns and require explicit approval gates for first-time/external contributors
- Scope service-account PATs (e.g. asyncapi-bot) to least privilege and rotate on a schedule
- Deploy CI egress monitoring/allowlisting (e.g. Harden-Runner-class tooling) to catch anomalous outbound connections during builds
- Do not treat npm OIDC/SLSA provenance as a proxy for commit legitimacy -- provenance proves the authorized workflow ran, not that the triggering commit was authored by a trusted party
Affected and fixed versions
- AsyncAPI Initiative — @asyncapi/generator (npm)
Vulnerable versions: 3.3.1
Fixed in: 3.3.0 (rollback) - AsyncAPI Initiative — @asyncapi/generator-helpers (npm)
Vulnerable versions: 1.1.1
Fixed in: 1.1.0 (rollback) - AsyncAPI Initiative — @asyncapi/generator-components (npm)
Vulnerable versions: 0.7.1
Fixed in: 1.0.0 - AsyncAPI Initiative — @asyncapi/specs (npm)
Vulnerable versions: 6.11.2; 6.11.2-alpha.1
Fixed in: 6.11.1 (rollback)
Timeline of AsyncAPI Miasma npm compromise
Last updated · 2 updates · revalidated 2× · latest source
- Security researcher reports a pull_request_target misconfiguration in asyncapi/generator's manual-netlify-preview.yml GitHub Actions workflow, warning it allows PR-controlled code to run with base-repository secrets.
- A fix for the manual-netlify-preview.yml pwn-request flaw is proposed but never merged, leaving the workflow exploitable.
- 07:51-08:28 UTC - Eleven commits in total are pushed to asyncapi/spec-json-schemas ahead of and between the @asyncapi/specs 6.11.2-alpha.1 and 6.11.2 publishes.
- 08:49 UTC - First observed downstream fetch of a malicious package version (specs@6.11.2) into a Yarn cache, confirming real-world propagation during the exposure window.
- 08:40 UTC - locked-ioc-49 is stripped of admin privileges and downgraded to read-only and all tokens are rotated; the compromised next branch was deleted at 07:44 UTC.
- 07:50 UTC - External researcher LidorMachluf publicly discloses the compromise via asyncapi/generator GitHub Issue #2184.
- 05:28 UTC - Maintainers begin incident response; the exploit PR is isolated by 06:09 UTC and the repository is locked to org-member-only PRs by 06:12 UTC.
- PR #2155 (commit 47be388), which triggered the PAT-stealing workflow run at 05:11 UTC (Run 29307859879), was closed by the attacker and a clean commit (ff010ef) force-pushed to mask the exploit from standard diff review.
- 05:04 UTC - Attacker begins flooding asyncapi/generator with 37 AI-generated pull requests to exhaust maintainer triage bandwidth ahead of the malicious PR #2155.
- 11:12-11:18 UTC - All five malicious package versions are unpublished from the npm registry; clean dist-tags restored.
- 08:06 UTC and 08:30 UTC - if-nodejs-release.yml publishes locked-ioc-31 and locked-ioc-43.
- 07:51-07:56 UTC - Same attacker pushes commit 36269ce81837 to the master branch of asyncapi/spec-json-schemas using the identical placeholder git identity.
- 07:10 UTC - release-with-changesets.yml auto-triggers via npm GitHub OIDC trusted publishing, publishing locked-ioc-37, locked-ioc-30, and locked-ioc-29 with valid SLSA provenance.
- 06:58 UTC - Attacker pushes commit 3eab3ec9304aa26081358330491d3cfeb55cc245 to the next branch of asyncapi/generator under the placeholder git identity 'Your Name <you@example.com>'.
- 05:16 UTC - The vulnerable manual-netlify-preview.yml workflow completes on PR #2155, exfiltrating a privileged Personal Access Token belonging to the locked-ioc-49 service account.
- 05:08 UTC - Attacker opens 37 pull requests against asyncapi/generator; nearly all add a fake charity donation page as noise, while PR #2155 hides obfuscated JavaScript after roughly 1,000 bytes of whitespace.
- Microsoft Threat Intelligence publishes its import-time payload delivery analysis with Defender detections and advanced hunting queries; it reports the credential-harvest, exfiltration, propagation, AI-tool-poisoning and sandbox-evasion modules present but disabled in the analyzed Stage 3 build, while RAT, C2 and persistence modules were active.
- AsyncAPI publishes its own official incident postmortem detailing root cause, four systemic failures, and remediation steps, alongside third-party technical analyses.
- Socket, StepSecurity, OX Security, Wiz, SafeDep, Aikido and The Hacker News publish coordinated technical analyses of the compromise and the Miasma-family payload.
Update history
- 2026-10-29 — AsyncAPI npm Supply Chain Compromise via GitHub Actions 'pwn request' (locked-ioc-47 / Miasma-linked import-time payload): What changed No field escalation. Severity (CRITICAL), exploitability (ACTIVE) and attribution confidence (LOW) are unchanged. The report lists status ACTIVE, but the existing MITIGATED status is kept: all five versions are unpublished and
- 2026-09-08 — AsyncAPI Supply Chain Compromise via GitHub Actions "Pwn Request" — Malicious @asyncapi npm Packages (July 2026): What changed CVSS newly established at 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H); severity (CRITICAL) and exploitability (ACTIVE) unchanged. The newer report's own status field says ACTIVE, but its narrative confirms the incident w
Sources cited for AsyncAPI Miasma npm compromise
- Compromised npm Packages in the AsyncAPI Namespace Deliver Miasma socket.dev · Research · 2026-07-15
- Coordinated AsyncAPI Supply Chain Attack: Miasma RAT Delivered via Compromised CI/CD Pipelines in Two Repositories stepsecurity.io · Research · 2026-07-15
- AsyncAPI npm organization compromised, 2M weekly downloads affected ox.security · Research · 2026-07-15
- M-Red-Team: AsyncAPI Supply Chain Compromise via GitHub Actions Wiz · Research · 2026-07-15
- AsyncAPI Packages Compromised with Miasma RAT safedep.io · Research · 2026-07-15
- AsyncAPI npm packages backdoored via GitHub Actions aikido.dev · Blog · 2026-07-15
- Compromised AsyncAPI npm Packages Deliver Miasma Tasking Framework via CI/CD Pipeline Hijack The Hacker News · News · 2026-07-15
- Miasma Supply Chain Attack Compromises Red Hat npm Packages with Credential-Stealing Worm The Hacker News · News · 2026-06-02
Previous and next in supply chain
Further reading
Drafted by the Threadlinqs research pipeline from 8 sources; published ; last updated .