Skip to main content

Command Palette

Search for a command to run...

AsyncAPI Under Attack: When 2 Million Downloads Per Week Becomes a Way to Spread Malware

Updated
16 min readView as Markdown
AsyncAPI Under Attack: When 2 Million Downloads Per Week Becomes a Way to Spread Malware

Campaign Summary

On July 14, 2026, attackers successfully compromised the AsyncAPI organization on npm — one of the most popular open source projects for event-driven APIs, and injected malicious code into 4 npm packages with a total of more than 2 million downloads per week. This is an extremely sophisticated software supply chain attack, combining three types of malware: info-stealer, crypto-stealer, and Remote Access Trojan (RAT).

What's especially dangerous: the attack does not use post-install scripts (which are blocked by npm v12), but instead embeds malicious code directly into the main JavaScript file of each package. Malware is activated as soon as the module is imported/required — making the npm install --ignore-scripts command completely useless.

Affected Packages

npm package Infected version Safe version Downloads/week (estimated)
@asyncapi/generator 3.3.1 3.3.0 ~100K
@asyncapi/generator-helpers 1.1.1 1.1.0 ~50K
@asyncapi/generator-components 0.7.1 0.7.0 ~50K
@asyncapi/specs 6.11.2, 6.11.2-alpha.1 6.11.1 ~2.7M

Event Timeline

Before the day of the attack

Time

Event

Significance

04/29/2026

The pull_request_target vulnerability in the asyncapi/generator repo is identified via a Proof-of-Concept.

Attackers (or third parties) knew how to exploit it early on.

05/17/2026

A fix is proposed via a Pull Request.

The fix has NOT been merged — leaving the exploitation window open for nearly 2 months.

07/14/2026

Date the attack takes place.

The vulnerability still exists on production.

Developments on July 14, 2026

Time (UTC)

Stage

Action

Technical Details

Impact

05:08

Stage 0 — Credential Theft

Opened 37 Pull Requests to the asyncapi/generator repo

One PR contained obfuscated JavaScript designed to execute in the pull_request_target workflow.

Created "noise" to hide the PR containing the actual malicious code.

05:08 – 06:57

Stage 0 — Credential Theft

CI/CD workflow triggered, exfiltrated the release bot's token

pull_request_target checked out the attacker's code instead of the base branch → ran malicious code with access to repository secrets.

Attacker obtained a legitimate npm publish token.

06:58

Stage 1 — Code Injection

Pushed malicious commit to the next branch

Used the stolen token to push directly into the repo.

Triggered the legitimate release pipeline.

07:10

Stage 1 — Package Publish

Published 3 generator packages to npm

The release-with-changesets.yml workflow automatically published via OIDC trusted-publisher.

@asyncapi/generator@3.3.1, generator-helpers@1.1.1, generator-components@0.7.1 — all carrying valid provenance.

08:06

Stage 1 — Package Publish

Published @asyncapi/specs@6.11.2

Same legitimate pipeline mechanism.

The package with ~2.7M weekly downloads began distributing malware.

08:30

Stage 1 — Package Publish

Published @asyncapi/specs@6.11.2-alpha.1

Additional alpha version published.

Expanded the blast radius to include early adopters.

08:30 – 11:18

Stage 2 — Active Exploitation

Malware executed on victim's machine upon import/require()

Spawned a detached Node.js process → downloaded sync.js from IPFS → decrypted Miasma RAT → established persistence + C2.

Developers and CI/CD runners infected when building/testing with the new packages.

~11:18

Response

Unpublished all 5 versions from the npm registry

AsyncAPI team responded after receiving alerts.

Stopped malware distribution via npm.

Hacker Profile

TeamPCP — Overview

The Shai-Hulud and Miasma campaigns are tracked by the security industry under a threat actor group called TeamPCP, also known by many aliases:

Name

Tracking Source / Description

PCP

Primary name, used by OX Security, JFrog, Snyk

DeadCatx3

Alias on underground forums

PCPcat

Variant name on some trackers

ShellForce / CipherForce

Alias tracked by some threat intelligence firms

CanisterWorm

Name based on worm technical characteristics

General characteristics:

  • Specializes in attacking software supply chains through open source registries (npm, PyPI, Cargo)

  • Exploit CI/CD pipeline, GitHub Actions, developer credentials to distribute malware at scale

  • Target open source "load-bearing" infrastructure — foundational packages relied on by millions of projects — to maximize blast radius

  • Operates under an organized cybercrime model, not a national APT (state-sponsored)

Campaign History — From Shai-Hulud To AsyncAPI

Time

Campaign

Target

Main Technique

Scale / Impact

09/2025

Shai-Hulud (Original)

General npm ecosystem

Self-replicating npm worm, install-time hooks (preinstall/postinstall), npm token + GitHub PAT theft.

Hundreds of packages infected; marked the turning point from typosquatting to automated worms.

04–05/2026

Mini Shai-Hulud (Wave 1)

TanStack, Mistral AI, Guardrails AI, UiPath

GitHub Actions "pwn request" + cache poisoning + OIDC token theft → published packages with valid SLSA Build Level 3 provenance.

First time in history: valid provenance was weaponized.

05/12/2026

Open-source Shai-Hulud

Hacker community

TeamPCP published the worm's source code on forums.

Turned a proprietary tool into "commodity malware" — anyone could create variants.

05/18/2026

Megalodon (Wave 2)

GitHub repositories

Pushed over 5,000 malicious commits to repos for large-scale secret exfiltration.

Brute-force attack on source code infrastructure.

05/19/2026

Wave 5

@antv ecosystem

Automated attack.

600+ packages compromised in 22 minutes.

06/2026

Miasma — Red Hat

@redhat-cloud-services npm packages

"Phantom Gyp" (malicious binding.gyp), Bun-staged loaders, preinstall hooks.

Dozens of Red Hat packages infected; credential stealers injected into frontend libraries.

06/2026

Miasma — LeoPlatform

LeoPlatform / RStreams

Phantom Gyp + Bun loaders, bypassed Node.js security tools.

Serverless data pipeline compromised.

07/14/2026

AsyncAPI (this analysis)

@asyncapi npm org (4 packages, ~2.9M weekly downloads)

CI/CD pwn request → import-time execution (bypassed ignore-scripts) → Miasma RAT + IPFS/Nostr/Ethereum C2.

Biggest evolution: no install hooks required, bypassed npm v12.

Detailed Technical Analysis

Phase 0 — Stealing Credentials via "Pwn Request"

The attack did not start from npm but from GitHub Actions. An attacker exploits a misconfiguration vulnerability in the CI/CD workflow:

  • 05:08 UTC: Attacker opens 37 pull requests to repository asyncapi/generator.

  • One of them contains obfuscated JavaScript designed to run in a workflow using the pull_request_target trigger.

  • Trigger pull_request_target executes with access to repository secrets — instead of a sandbox like pull_request, Workflow has already checked out the attacker's code instead of the base branch, allowing the release bot's token to be exfiltrated

After having the token, the attacker:

  1. Push the malicious commit to the next branch at 06:58 UTC

  2. This action triggers the legal workflow release-with-changesets.yml

  3. Packages are published through GitHub's OIDC trusted-publisher system

  4. Result: Packages carry valid provenance/SLSA attestation — because they are published via the official GitHub Actions pipeline

Phase 2 — Import-Time Execution

Malicious code does NOT use install hooks (post-install script). Instead:

  • Malicious code is embedded inside a legitimate source code file

  • When the module is loaded (require() or imported), it spawns a separate Node.js process (detached).

  • This process loads the encrypted loader (sync.js) from IPFS

  • Then decode and deploy the full Miasma framework

Direct consequence: npm install --ignore-scripts does NOT protect against this attack.

Malware Analysis — Payload Miasma RAT

Scale and Complexity

  • 91,973 lines of code — this is not "quickly written" malware

  • Hybrid combination: Info-stealer + Crypto-stealer + RAT + Worm

  • Cross-platform: Supports Linux, macOS, Windows

Persistence (Maintained on the System)

Miasma installs sync.js into a folder pretending to be NodeJS for each platform:

OS Persistence path
Linux ~/.local/share/NodeJS/sync.js
macOS ~/Library/Application Support/NodeJS/sync.js
Windows %LOCALAPPDATA%\NodeJS\sync.js

Persistence mechanism:

  • Linux: Create systemd unit miasma-monitor.service

  • macOS: Repair startup shell files (.bashrc, .zshrc, etc.)

  • Windows: Registry Run key

C2 Infrastructure (Command & Control)

Malware uses multi-layer, resilient C2 architecture:

The use of IPFS, Nostr, Ethereum smart contract, and BitTorrent DHT as backup C2 channels shows that the attacker is highly skilled and designed to withstand takedown — even if the main C2 is taken down, the malware still has many alternative communication routes.

Data Collection Capabilities

Malware comprehensive collection:

  • Browser passwords (all major browsers)

  • SSH keys

  • npm tokens, GitHub tokens

  • AWS credentials and cloud config

  • Cryptocurrency wallets (Many types of wallets)

  • Clipboard data

Worm-like Propagation

This is the most dangerous feature for the developer environment:

If the malware detects a valid authentication token for npm, PyPI, or Cargo, it will attempt to publish itself to packages the victim manages on those registries.

One infected developer = new distribution vector. The chain of contagion can expand exponentially.

Anti-Analysis Mechanism

Malware performs many checks before operating:

Check / Condition

Action if TRUE

Running in a Virtual Machine (VM)

Terminate

EDR / Endpoint Protection detected

Terminate

System locale/language is Russian

Terminate

Checking the Russian locale is typical of malware of Russian or CIS origin — the attacker does not want to infect his own or his allies' machines.

Risk Summary

Operation Miasma/Shai-Hulud by the TeamPCP group (or copycat variants) poses an extremely serious level of risk to technology businesses and the open source community:

  1. Worm-like Propagation Risk:

    • Malware automatically hunts for authentication tokens of popular registries (npm, PyPI, Cargo). If a programmer's workstation maintains any infected library, the malicious code will automatically package and publish the malicious version to that library. This creates an exponential chain reaction of infection.
  2. High-Value Credential Theft risk:

    • Not only stealing browser passwords or regular cryptocurrency wallets, this campaign focuses heavily on technical secrets: AWS/GCP/Azure credentials, Kubernetes/Vault tokens, SSH keys, GitHub Personal Access Tokens (PATs). Loss of this information can lead to the organization's entire cloud infrastructure being controlled.
  3. Risk of disabling traditional security shields (Security Bypass Risk):

    • Bypass SLSA Provenance: The attacker does not publish directly but hijacks the legitimate release stream (CI/CD pipeline) of the original project. Therefore, cryptographically based origin authentication mechanisms (OIDC, SLSA Build Level 3) both confirm the packet as "secure", disabling automatic filters that check digital signatures.

    • Bypass Static Scan & Ignore-scripts: By executing at the moment the import or require command is called (import-time execution) instead of using install-hooks, installation isolation security settings (--ignore-scripts) are completely bypassed.

Why Do Current Measures Fail?

Security Measure

Status

Reason / Details

npm install --ignore-scripts

Ineffective

Malware does not use install hooks; it executes upon import/require().

npm Provenance / SLSA Attestation

Bypassed

The package was published via a legitimate CI/CD pipeline → the attestation is valid.

SCA (Software Composition Analysis)

Not detected

Newly published version → not yet in threat intelligence databases.

npm v12 post-install block

Not applicable

Attacker embedded the code directly into the main JS file, no post-install script needed.

Lockfile pinning (npm ci)

Partial protection

Only protects if a safe version is already pinned; does not protect during new npm installs or dependency bumps.

Indicators of Compromise (IOCs)

Network IOCs

Type Value Purpose
C2 Server 85[.]137[.]53[.]71 Primary C2
C2 Ports 8080, 8081, 8091 Command, Data Exfil, Backup
IPFS Gateway ipfs.io Payload hosting & Fallback C2
BitTorrent router.bittorrent.com Backup beaconing
BitTorrent router.utorrent.com Backup beaconing
BitTorrent dht.transmissionbt.com Backup beaconing

Blockchain IOCs

Type Value
Ethereum Address 0x12c37A86a0Ed0beBe5d1d6a43E42f07860eAc710

File System IOCs

OS Path
Linux ~/.local/share/NodeJS/sync.js
macOS ~/Library/Application Support/NodeJS/sync.js
Windows %LOCALAPPDATA%\NodeJS\sync.js
Linux systemd unit miasma-monitor.service

Affected Package Versions

Package Malicious version
@asyncapi/generator 3.3.1
@asyncapi/generator-helpers 1.1.1
@asyncapi/generator-components 0.7.1
@asyncapi/specs 6.11.2, 6.11.2-alpha.1

MITER ATT&CK Technical Map

Tactic

Technique ID

Technique Name

Application in Campaign

Reconnaissance

T1595

Active Scanning

Attackers scan public repositories to find GitHub Actions misconfigurations (especially the abuse of the pull_request_target trigger).

Initial Access

T1190

Exploit Public-Facing Application

Exploited the pull_request_target misconfiguration in the asyncapi/generator repository to gain Runner privileges.

Initial Access

T1195.002

Supply Chain Compromise: Compromise Software Dependencies

Embedded malicious code directly into the main JavaScript file of npm packages, distributed through official release channels.

Execution

T1204.002

User Execution: Malicious File

Malware executes when developers or CI/CD systems import/require the infected library packages.

Execution

T1059.003

Command and Scripting Interpreter: Windows Command Shell

Executed system scripts to configure hidden background processes.

Execution

T1059.004

Command and Scripting Interpreter: Unix Shell

Ran shell scripts on macOS/Linux to set up the malware.

Persistence

T1543.003

Create or Modify System Process: Systemd Service

Created a systemd service named miasma-monitor.service on infected Linux machines.

Persistence

T1547.001

Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder

Overwrote the Run key in the Windows Registry and modified shell startup files (.bashrc, .zshrc) on macOS to maintain control.

Defense Evasion

T1140

Decompile, Decrypt, or Deobfuscate Files/Information

Decrypted the encrypted loader file sync.js downloaded from IPFS before execution.

Defense Evasion

T1497.001

Virtualization/Sandbox Evasion: System Checks

Checked if the system is running in a virtualized environment (VM) or analysis sandbox to self-terminate.

Defense Evasion

T1497.003

Virtualization/Sandbox Evasion: Time-based Evasion

Checked the system locale/language (Russian) to evade EDR/Sandbox detection and self-terminate.

Defense Evasion

T1036

Masquerading

Named malware storage directories to masquerade as legitimate Node.js system directories (e.g., %LOCALAPPDATA%\NodeJS).

Credential Access

T1555

Credentials from Password Stores

Collected saved passwords from popular web browsers on the victim's machine.

Credential Access

T1552.001

Unsecured Credentials: Private Keys

Scanned and collected SSH private keys stored on disk.

Credential Access

T1552.004

Unsecured Credentials: Private Information in Cloud / Code

Searched for authentication tokens of npm, PyPI, Cargo, GitHub, and Cloud configuration credentials (AWS, GCP, Azure).

Discovery

T1082

System Information Discovery

Queried system configuration information, time zone, and locale language to check geofilters.

Command and Control

T1071.001

Application Layer Protocol: Web Protocols

Used HTTP/HTTPS over ports 8080/8081/8091 to connect to the main C2 at 85.137.53.71.

Command and Control

T1568

Dynamic Resolution

Leveraged the Nostr protocol, IPFS Gateways, and Ethereum smart contracts to resolve and fallback to C2.

Command and Control

T1105

Ingress Tool Transfer

Downloaded the next payload file (sync.js) from the IPFS P2P network.

Command and Control

T1043

Commonly Used Port

Used standard BitTorrent DHT ports for beaconing communication to bypass firewalls.

Exfiltration

T1048

Exfiltration Over Alternative Protocol

Exfiltrated stolen sensitive data through P2P backup channels and BitTorrent DHT.

Impact

T1496

Resource Hijacking

Deployed secondary features related to crypto-stealers (draining funds from crypto wallets) and RATs for resource hijacking.

Impact

T1565

Data Manipulation

Automatically modified library packages managed by the victim on npm/PyPI/Cargo to self-replicate.

Response Recommendations

Take Action Immediately

  1. Revoke & Rotate Tokens: Immediately revoke all developer tokens (npm, PyPI, Cargo, GitHub) on any machines that may have been running affected packages

  2. Check the version in use: If package-lock.json or node_modules contain any affected versions → consider that machine compromised

  3. Rotate secrets: Change all SSH keys, AWS credentials, API keys on the suspected infected machine

  4. Check file system: Search for sync.js in IOC paths on all developer machines and CI/CD runners

Monitoring and Detection

  1. Monitor outbound traffic: Monitor connections to 85[.]137[.]53[.]71, BitTorrent bootstrap nodes, and IPFS gateways — this is unusual in a typical development environment

  2. Audit registry releases: Check all recent commits and package releases on the organization's registry to detect unauthorized code injection

  3. Check systemd services: On Linux, search for unit miasma-monitor.service

Long Term Defense

  1. Lockfile pinning: Always use npm ci instead of npm install in CI/CD

  2. Stability buffer: Apply a policy of not using newly published packages in the first 48–72 hours

  3. Build-time egress control: Deploy a firewall for the build environment (Build Application Firewall), blocking outbound traffic to unapproved destinations

  4. GitHub Actions security:

    • DO NOT use pull_request_target with actions/checkout on PR code

    • Review and audit all workflows that use repository secrets

    • Merge security fixes promptly — the vulnerability has been known since April but the fix was not merged until July

  5. Monitor import-time behavior: Deploy a solution to detect malicious code executing at require()/import time — not just at install

Lessons Learned

For Developers and DevOps

  • Provenance ≠ Trust: Valid Provenance only proves that the package was built from the official pipeline, NOT that the code inside is safe. If the pipeline is compromised, the provenance is still valid.

  • Ignore-scripts are not enough: When malware is embedded in the source code instead of the install hook, this measure becomes meaningless.

  • CI/CD is the attack surface: The attack starts from GitHub Actions misconfiguration — an area that is often outside the scope of scanning by dependency scanners.

For Organizations

  • Supply chain attacks are increasingly complex: Attackers combine CI/CD compromise + import-time execution + multi-layer C2 + worm propagation + false flag attribution.

  • npm v12 is not enough: Blocking post-install scripts is a step forward but doesn't address the root cause — attackers just need to move the attack vector to import-time.

  • Build-time egress control is the most important layer of defense that most pipelines do not yet implement — it is the only layer that can detect and block C2 callbacks.

Reference

AsyncAPI npm organization compromised, 2M weekly downloads affected

AsyncAPI npm Supply Chain Attack: Malware Injected Into Packages With 2 Million Weekly Downloads

AsyncAPI npm Supply Chain Attack Delivers Miasma RAT

M Red Team: AsyncAPI Supply Chain Compromise via GitHub Actions

More from this blog

F

FPT IS Security

981 posts

Dedicated to providing insightful articles on cybersecurity threat intelligence, aimed at empowering individuals and organizations to navigate the digital landscape safely.