THREAT BRIEFING · 12.08.2026 DEENFRES

Practice & Implementation

CI/CD Published AsyncAPI Botnet Loader

By Alec Chizhik · July 17, 2026 · 7 min read

Four AsyncAPI npm packages ran on July 14, 2026 with valid OIDC provenance and still delivered a multi-stage botnet loader. The entry point was in the CI: a misconfigured pull_request_target workflow, followed by a push to the release branch via bot‑controlled credentials. npm Trusted Publishing remained technically sound and did not cover the upstream trust breach.

Key Takeaways

  • The entry point was in the CI misconfig, long before the registry token. pull_request_target with checkout of the untrusted head, broad GITHUB_TOKEN and subsequent bot push: secret exfiltration and branch compromise go hand in hand.
  • Payload at require(), the active runtime was slimmer than the bundle. ShellExec, persistence and C2 ran. Harvesting, propagation and evasion were in the package, toggleable in this release.
  • Lockfiles from the 07:10-11:18 UTC window remain risky. npm unpublishes the versions; existing pins and CI caches not.

Related:An npm package that stole private keys  /  Mini Shai-Hulud: npm Supply-Chain Worm and Defense

What exactly happened

On July 14, 2026 at 06:58 UTC, a commit landed in the asyncapi/generator repository on the branch next under the placeholder identity “Your Name” / you@example.com. Twelve minutes later, the legitimate workflow release-with-changesets.yml published three packages with valid npm-OIDC provenance: @asyncapi/generator@3.3.1, @asyncapi/generator-helpers@1.1.1 and @asyncapi/generator-components@0.7.1.

According to the Microsoft Security Blog, the initial access previously occurred via PR #2155 against the workflow manual-netlify-preview.yml. The workflow used pull_request_target and checked out the untrusted head commit. The GITHUB_TOKEN was broadly privileged; checkout credentials remained in the local Git config until the post-job cleanup. Subsequently, it was pushed using the asyncapi-bot account. Microsoft cautiously suggests that exactly this credential may have been compromised. While the pwn-request entry point and the subsequent bot-push chain are documented and explain the move into the release branch, they do not definitively prove that this specific credential was stolen.

Important for context: there was no stolen npm publish token. The publish path ran through OIDC trusted publishing. The trust breach occurred earlier, in the CI and push rights on the branch that triggers the release workflow.

~4 h

Exposure window until unpublishing of Generator packages

Source: StepSecurity-Timeline, July 14, 2026 UTC

Why “Valid Provenance” Falls Short Here

npm Trusted Publishing, using OIDC and SLSA attestations, answers a sharp question: Was this artifact generated by the authorized GitHub workflow of this repository? The attestation for the generator packages displayed precisely repo:asyncapi/generator:ref:refs/heads/next, the workflow file, commit SHA and run URL.

What they do not address: Was the commit that triggered the workflow legitimate and clean? Provenance does not guard against compromised push credentials nor against CI jobs that execute untrusted code with privileged tokens. Anyone who combines pull_request_target with checkout of the PR head, retains secrets in such jobs and keeps branch protection lax on release branches, opens precisely this chain.

For CISOs and AppSec this is the central lever: Registry signatures and provenance flags alone deem the AsyncAPI case “green”, even though the CI had already shipped the dropper. Controls must verify the source‑of‑truth and workflow permissions.

Payload Mechanics Without Install Hook

In none of the affected package.json files was there a preinstall/postinstall script. The dropper started as soon as the poisoned module code was loaded via require(), i.e., during the normal generator run or in CI jobs building AsyncAPI templates.

Stage 1 spawns a dedicated Node process. Stage 2 fetches a sync.js from an IPFS gateway, stored under OS‑specific paths that appear as a benign NodeJS runtime (e.g., ~/.local/share/NodeJS/sync.js on Linux). Stage 3 decrypts a bundled Miasma‑v3 implant. In the delivered configuration, Remote‑Shell (ShellExec), Persistence and C2 Beaconing ran over multiple channels (HTTP, Nostr, IPFS, BitTorrent‑DHT, Ethereum‑Dead‑Drop).

Static analyses by Aikido and Socket also reveal modules in the bundle that were disabled via toggle in this release: recon: false (Credential harvesting does not start), metamorphic: false (Mutation, evasion and AI‑tool poisoning disabled) as well as propagate for npm/pypi/ruby/cargo consistently false (no lateral package propagation). The store was in the artifact. The runtime of this wave was a remote shell with persistence and C2. Host forensics remains mandatory because shell access and persistence were active.

Package Malicious Version Safe Version
@asyncapi/generator 3.3.1 3.3.0
@asyncapi/generator-helpers 1.1.1 1.1.0
@asyncapi/generator-components 0.7.1 0.7.0 / 1.0.0
@asyncapi/specs 6.11.2 / 6.11.2-alpha.1 6.11.1

Source: StepSecurity Affected-Packages-Table, as of 14.07.2026

What Security Teams Should Check Now

First, perform a facts check in your own inventory: lockfiles and CI caches from the UTC window of 14. July. Whoever pulls @asyncapi/specs only transitively via the parser often does not see the version in the direct dependency tree. Overrides and SBOM scans are mandatory here.

Second, host forensics: drop paths under the misleading ‘NodeJS’ name, detached Node processes, outbound connections to IPFS gateways and unusual HTTP C2 targets. Third, credential rotation on affected runners and laptops. ShellExec can reach environment secrets and local tokens, even if the bundled harvesting module is out of the box. Priority: GitHub PATs, npm tokens and cloud keys from build environments.

Immediate Actions

  • Regenerate lockfiles, enforce safe version pins
  • Check drop paths and detached Node processes on dev and CI hosts
  • Rotate secrets on affected machines
  • pull_request_target: no checkout of untrusted heads with secrets; least‑privilege tokens
  • Release branches: review required, signed commits, direct push disabled
  • CI egress: only expected registry destinations, block IPFS/DHT by default

Structurally, a cooldown for freshly published npm versions and runtime egress controls in GitHub Actions pay off. Provenance remains useful as a layer above CI hardening, branch protection, dependency cooldown and behavior telemetry in the build.

Perspective for DACH Enterprises

AsyncAPI is embedded in API generators, documentation pipelines and DevOps toolchains. Those who adopt event‑driven architectures and automate OpenAPI/AsyncAPI are often using the packages indirectly. The NIS2 directive and the Cyber Resilience Act tighten expectations around supply‑chain risk management. The claim “we verify provenance” alone isn’t sufficient when workflow permissions and branch governance remain open.

This case highlights governance at the source‑of‑truth: the Git branch and the CI workflows that feed the pipeline. Registry attestations add to this layer but do not replace it as the sole proof of trust.

Frequently Asked Questions

Every question is locked. A tap unlocks the answer.

Did the npm provenance not serve as proof of trust?

It proves the authorized workflow and the build context. The legitimacy of the triggering commit and the integrity of upstream CI credentials does not cover it. In the event of a branch compromise, the attestation can be technically correct but misleading for the risk question.

Would a blocker for install scripts have prevented it?

No. The dropper relied on the module load (require). npm lifecycle scripts were left out of the protection. Security requires behavioral and egress controls in the build.

Are fresh installations still dangerous today?

The malicious versions have been removed from the registry. Risky remain lock files and caches from the exposure window as well as hosts that have already executed the payload.

Which credentials rotate first?

On affected development and CI systems: GitHub and npm tokens, SSH keys and cloud credentials that were stored in the environment or in runner secrets. The justification is shell access plus persistence. The harvesting module was included in this release via this configuration.

What is the priority governance measure?

Audit pull_request_target and associated privileged workflows (no untrusted checkout with secrets, use least‑privilege tokens), lock down release branches (require reviews, enforce signed commits, block direct pushes) and limit CI egress. Provenance supplements this by providing proof of the build pipeline.

Lesetipps der Redaktion

LesetippCursor startet git.exe aus dem Repo-RootLesetippLegacyHive-PoC trifft frische Windows-PatchesLesetippZwei Joomla-Uploads landen im CISA-KEV

Mehr aus dem MBF Media Netzwerk

cloudmagazinWenn KI-Agenten reisen: Data-Residency als Operating-ProblemMyBusinessFutureMehr Insolvenzen, kleinere Fälle: Was zähltDigital ChiefsToken-OPEX: Inference steuert, nicht das Seat-Budget

Further reading

Practice & Implementation · July 31, 2026

Anthropic: Claude Breached Three Companies

Anthropic's Claude compromised three organizations in cyber evaluations. Harness misconfiguration, PyPI malware, and CISO checklist insights.

Practice & Implementation · July 29, 2026

Codex Security: Open Client Feeds OpenAI

Codex Security CLI: open-source client code under Apache 2.0, scanning backend in limited beta against OpenAI infrastructure.

A magazine by Evernine Media GmbH