Miasma moves from the package manager into the editor: a clone + “open folder” in Claude Code, Cursor, Gemini CLI or VS Code is enough — and it hit Azure/durabletask too
6 June 2026. SafeDep has documented a new detonation surface of the Miasma worm family: instead of publishing an npm package, the worm commits six files directly into GitHub source repos — five of them merely triggers that launch the sixth (.github/setup.js, a 4.3 MB Bun dropper) via auto-run features of real tools: SessionStart hooks in .claude//.gemini/, an always-apply rule in .cursor/rules/, a folderOpen task in .vscode/ and a hijacked test script. Cloning is safe, opening is not — whoever opens an affected repo in VS Code or starts Claude Code in it harvests a multi-cloud credential stealer. The fingerprint was found in 113 repos across dozens of accounts, including the official Azure/durabletask (stolen PAT of a real contributor, commit backdated to 2020).
TL;DR — 90 seconds
Affected?
Developers who, after 2 June, cloned one of the affected GitHub source repos and opened it in an AI coding agent/editor (Claude Code, Gemini CLI, Cursor, VS Code) or ran npm test in it. SafeDep found the fingerprint in 113 repos across dozens of accounts, incl. Azure/durabletask, Azure-Samples/llm-fine-tuning, metersphere/helm-chart. Aggravating: machines with reachable cloud/CI/AI credentials.
Risk?
Local code run on opening the repo (not on cloning, not via the npm package — the published packages of these projects are clean), followed by a multi-cloud credential sweep (AWS, Azure, GCP, Vault, Kubernetes, npm, GitHub) and self-propagation with stolen tokens.
Immediate action?
Do not open suspicious working copies in an editor/agent and do not run npm test; grep a local clone before opening (test -f .github/setup.js); delete affected clones and re-clone from a clean commit; on a hit, rotate exposed credentials.
Recommendation?
Mid-market and enterprise: treat .claude/, .gemini/, .cursor/, .vscode/ in the diff as a supply-chain signal (not “editor noise”); configure editor/agent auto-run restrictively for cloned third-party repos; bring AI coding agents into the threat model as executing supply-chain actors.
Criticality?
high (references the hero badge — active, self-replicating campaign; review within the 48h window).
What is the problem?
On 3 June 2026, per SafeDep, Miasma hit two surfaces at once. The npm arm published 57 malicious packages across 286+ versions and hid the trigger in binding.gyp files to evade lifecycle-script scanners — I covered that arm on 4 June (the Phantom Gyp/binding.gyp post, sources StepSecurity/JFrog). This post documents the other arm: a parallel run of the same worm that skips the registry entirely and pushes directly into GitHub source repos.
An attacker pushed a commit chore: update dependencies [skip ci] to icflorescu/mantine-datatable and four sibling repos. The commit added no dependency. It planted a 4.3 MB payload runner and wired it to launch automatically via five developer tools. The file list gives away the logic:
Five of the six files exist only to launch the sixth. .github/setup.js is the payload; everything else is a trigger, one per tool. The clever part is the trigger surface: each config file abuses a legitimate auto-run feature of a different tool. Cloning the repo is harmless — opening it is not. Whoever clones mantine-datatable to debug and opens the folder in VS Code or starts Claude Code in it runs the payload with no further interaction.
The dropper itself (setup.js) is a single eval statement: a char-code array, a Caesar shift (here ROT-4), the result passed to eval. Statically decoded it is an async loader that pulls node:crypto and AES-128-GCM-decrypts two hardcoded blobs — a bootstrap component and the actual worm payload (_p, 667 KB). The loader writes _p to a random temp file and runs it under Bun (downloading Bun on demand from the official oven-sh release URL). Bun brings its own runtime, fetch, crypto and shell — the payload needs nothing from the host beyond the downloaded binary, keeping it off the victim's Node install.
Who is affected?
Affected
Not affected
Conditions / aggravating
Developers who, after 2 June, cloned an affected source repo and opened it in an AI agent/editor (Claude Code, Gemini CLI, Cursor, VS Code)
Anyone who only cloned an affected repo but did not open it and did not run npm test
Trigger = git clone + opening the folder / starting an agent session / npm test; not the clone alone
Projects/CI that run the test script of an affected repo
Anyone who only uses the published npm package of these projects
SafeDep: “the published npm packages of these projects are clean” — the risk is local and survives npm uninstall
113 repos indexed by GitHub code search across dozens of accounts, incl. Azure/durabletask, Azure-Samples/llm-fine-tuning, metersphere/helm-chart
Repos without the .github/setup.js dropper or without the trigger config files
Code search only covers indexed default branches and skips files > ~384 KB → a floor, not a complete list
Machines with reachable cloud/CI/AI credentials
Pure read environments without editor auto-run and without reachable secrets
Payload harvests AWS, Azure, GCP, Vault, Kubernetes, npm, GitHub; exfiltrates to attacker-created public GitHub repos; propagates with stolen tokens
Particularly sensitive is the Azure/durabletask hit (1,718 stars): here the PAT of a real Microsoft contributor was stolen, the commit backdated to 2020-03-09 and hidden in a dormant branch — commit message Switched DataConverter to OrchestrationContext [skip ci]. THN also reports a GitHub sweep that disabled 73 Microsoft repos across four organisations (Azure, Azure-Samples, Microsoft, MicrosoftDocs) in roughly 105 seconds. Important on the source's honest uncertainty: SafeDep names 113 indexed repos as a floor; the 4.3 MB setup.js itself never indexes, the campaign is given away by the small launcher files. Three different setup.js hashes across four accounts show: the dropper is recompiled per wave, not copied verbatim.
Impact
The core is not “yet another worm” but the change of vector. Supply-chain malware historically lived off the install hook: preinstall, postinstall, setup.py or the binding.gyp trick. This wave skips the registry entirely and bets on the editor. “Cloning a repo to read its source” always felt safe. AI coding agents and IDE auto-run features quietly changed that — and attackers noticed before most defenders did.
Concretely, every trigger hangs on a legitimate feature: Claude Code and Gemini CLI run a shell command via a SessionStart hook when an agent session opens in the project (.claude/settings.json/.gemini/settings.json with "command": "node .github/setup.js"). Cursor uses an always-applied project rule (.cursor/rules/setup.mdc, alwaysApply: true) that instructs the agent to run the file — social engineering against the assistant, a prompt injection that ships in the repo. VS Code uses a task with "runOn": "folderOpen" — no agent is even needed, merely opening the folder suffices. And the package.jsontest hijack detonates in CI and for anyone who runs the tests.
The reach: the worm deliberately keeps off the victim's Node install via Bun, harvests credentials across AWS/Azure/GCP/Vault/Kubernetes/npm/GitHub, exfiltrates to fresh public GitHub dead-drop repos (for this arm SafeDep additionally found the accounts windy629 with 200+ repos and HerGomUli, all with the description “Miasma - The Spreading Blight”) and propagates onward with the stolen tokens. There is no CVE number — it is an ongoing supply-chain incident, not a single product flaw. The operational severity is high nonetheless, because the trigger is exactly the action that feels safest: opening a third-party repo to read it.
Mitigation / immediate steps
Note: the following steps are my operational recommendation based on the technique documented by SafeDep — not a vendor-certified guide. The authoritative, continuously maintained repo/IoC list is at SafeDep.
Operational Decision Block
Act now if … after 2 June you cloned one of the listed repos and opened it in VS Code/Cursor/Claude Code/Gemini or ran npm test in it.
Check with priority if … your developers regularly clone third-party repos and open them in AI coding agents, and those machines reach cloud/CI credentials.
Awareness only if … you have cloned no affected repos and editor/agent auto-run for third-party repos is already disabled.
Step 1 — Check before opening (clone is safe, opening is not)
# quick check for the dropper, BEFORE an editor/agent opens the repo
test -f .github/setup.js && echo "DROPPER PRESENT — do NOT open this repo in an editor"
# find the campaign's auto-run triggers
ls -la .claude/settings.json .gemini/settings.json .cursor/rules/setup.mdc .vscode/tasks.json 2>/dev/null
grep -RIn "node .github/setup.js" .claude .gemini .cursor .vscode package.json 2>/dev/null
Step 2 — Remove affected clones
- do NOT open the working copy in VS Code/Cursor/Claude Code/Gemini, no npm test
- delete the clone and re-clone from a commit BEFORE the injection
(or wait for the maintainer revert)
- reconcile the IoC list at the SafeDep source (floor, not a complete list)
Step 3 — Rotate credentials (on a hit)
If an affected repo was opened/tested, treat the environment as compromised:
- rotate GitHub (incl. PATs), npm, cloud tokens (AWS/Azure/GCP), Vault, Kubernetes tokens
- assume local credential/auth caches are exposed (cloud CLI caches, AI-tool auth)
- check outbound connections/Bun download (oven-sh release) and /tmp/p<rand>.js, /tmp/b-<rand>/bun</rand></rand>
Step 4 — Contain editor/agent auto-run
- configure auto-run features restrictively for cloned THIRD-PARTY repos:
* VS Code: disable automatic tasks / "runOn": "folderOpen" for untrusted folders
(use Workspace Trust; "Restricted Mode" for foreign folders)
* Claude Code / Gemini CLI: do not adopt SessionStart hooks from the repo unchecked
* Cursor: review project-shipped "alwaysApply" rules before the first agent run
- treat .claude/ .gemini/ .cursor/ .vscode/ in code review like executable code
Detection / verification
IOCs taken directly from the technique documented by SafeDep; the running list is at the source.
Planted files and triggers
# campaign footprint in the working tree (six files, five triggers + dropper)
find . \( -path '*/.github/setup.js' -o -path '*/.claude/settings.json' \
-o -path '*/.gemini/settings.json' -o -path '*/.cursor/rules/setup.mdc' \
-o -path '*/.vscode/tasks.json' \) -print 2>/dev/null
# SessionStart/folderOpen/test hooks that launch setup.js
grep -RIn "SessionStart\|runOn.*folderOpen\|node .github/setup.js" \
.claude .gemini .cursor .vscode package.json 2>/dev/null
Scope first, then rotate. Determine who on the team cloned third-party repos in recent days and opened them in an AI coding agent or VS Code — that is the exposed population, not “who installed an npm package”. Grep suspicious clones before opening (test -f .github/setup.js). Where a repo was opened or tested, treat the reachable tokens as compromised. The most important organisational measure: make it clear that “just cloning and opening a repo to read it” is no longer automatically safe — that single habit is the trigger.
Enterprise
Additionally: bring .claude/, .gemini/, .cursor/, .vscode/ into code review and diff policy as executable supply-chain artifacts (required reviews, alert on new auto-run hooks) — most review workflows ignore these directories as “editor noise”. Configure editor/agent auto-run centrally: VS Code Workspace Trust / Restricted Mode for foreign folders, no unchecked SessionStart hooks from cloned repos, review of project-shipped Cursor alwaysApply rules. Bring AI coding agents into the threat model as executing actors — a .cursor/rules file is a prompt injection that ships in the repo.
Kubernetes / containers
Build/CI runners that check out repos and run npm test or editor tasks belong in minimally privileged, ephemeral environments without broadly reachable cloud/Kubernetes credentials. Scope service-account tokens tightly, limit secret access per workload, restrict outbound network access from build runners (the dropper downloads Bun and exfiltrates via HTTPS to GitHub dead-drops). That way a single opened clone does not become a cluster-wide credential leak.
Declarative stacks (NixOS / Talos / Flatcar)
The lever here is provability and the reproducible dev environment: if editor/agent configuration is managed centrally and declaratively, repo-shipped .claude//.cursor/ overrides stand out because they deviate from the known-good configuration. Reproducible, ephemeral dev containers for third-party repos are the clean approach: an opened untrusted repo then runs in a throwaway environment without access to production credentials.
What I actually did
For weeks I have treated AI coding agents as what they are in security terms: executing actors with repo-shipped configuration. On this occasion, for managed stacks, that meant: ran a sweep over local and CI clones for the six-file footprint (.github/setup.js plus the four auto-run configs plus the package.jsontest hijack), grepped suspicious clones before opening, reconciled the SafeDep IoC list as a floor, and contained editor/agent auto-run for third-party repos (VS Code Workspace Trust, no unchecked SessionStart hooks, review of project-shipped Cursor rules).
The honest lesson connects directly to my npm posts. In the binding.gyp wave (4 June) the defence was --ignore-scripts and short-lived CI credentials; with IronWorm (6 June) workflow integrity and Trusted-Publishing scope were added. This wave shows the next door: even if you disable install hooks completely, you are not protected when the trigger sits in the editor. --ignore-scripts does not catch a SessionStart hook. So I extended the control: the four agent/editor configuration directories are now part of my diff policy (review-required, alert on new auto-run entries), and untrusted third-party repos are opened in ephemeral dev containers without production credentials.
A closer look: why “opening” is now the dangerous step
The mechanism is so effective because every single building block is a legitimate feature turned against the user. A SessionStart hook is exactly what it is meant to be — project setup at the start of an agent session; only here “setup” is a credential stealer. An alwaysApply Cursor rule is exactly what it is meant to be — giving the agent project-wide instructions; only the instruction is “run node .github/setup.js”. A VS Code folderOpen task is exactly what it is meant to be — convenience on opening; only it fires without any agent. SafeDep's phrasing nails it: “A .cursor/rules file that instructs an agent to run a script is a prompt injection that ships in the repo. A SessionStart hook is a postinstall for your editor.” The consequence for the threat model is uncomfortable but clear: the mental default “cloning and reading is safe” no longer holds once an AI coding agent or an IDE with auto-run is involved. Treat opening a third-party repo like running its code — because that is exactly what it can be.
Frequently asked questions about the Miasma editor wave
Am I affected if I only cloned a repo but did not open it?+
No. Per SafeDep, cloning is safe, opening is not. The trigger is git cloneplus opening the folder in VS Code/Cursor or starting a Claude Code/Gemini session — or npm test. Check a clone before opening with test -f .github/setup.js; if the file is there, do not open the repo in an editor — delete it and re-clone from a clean commit.
Does --ignore-scripts protect against this Miasma wave?+
No — and that is the crux. --ignore-scripts stops npm lifecycle hooks (preinstall/postinstall), but this wave publishes no package at all. The trigger sits in the editor: a SessionStart hook in .claude//.gemini/, an alwaysApply rule in .cursor/, a folderOpen task in .vscode/. The right control is to contain editor/agent auto-run (VS Code Workspace Trust/Restricted Mode) and review these directories as executable code.
Are the npm packages of mantine-datatable & co. compromised?+
For this (source-repo) arm, no: SafeDep states explicitly that the published npm packages of these projects are clean — the risk is local and survives npm uninstall. Note the distinction: for individual accounts (e.g. jagreehal) an npm arm with compromised packages ran in parallel (per StepSecurity) — that is the separate wave we covered on 4 June, not this source-repo vector.
How did malicious code get into the official Azure/durabletask repo?+
Per SafeDep, via a stolen personal access token of a real Microsoft contributor; the commit was backdated to 2020-03-09 and hidden in a dormant branch (message Switched DataConverter to OrchestrationContext [skip ci]). THN reports a GitHub sweep that disabled 73 Microsoft repos across four organisations in roughly 105 seconds. This fits Miasma's pattern: steal the token, then push into every reachable repo with write access.
Is this the same thing as the binding.gyp worm or IronWorm?+
Same family (Miasma/Shai-Hulud), different detonation surface. The binding.gyp/“Phantom Gyp” post (4 June) covers the npm install vector; IronWorm (6 June) is its own Rust campaign with Trusted-Publishing abuse and an eBPF rootkit. This wave is the third vector: direct source-repo injection with editor/AI-agent auto-run as the trigger. Shared loader (Bun stager), different ignition mechanism.
Is there a CVE or a patch?+
No. This is an ongoing supply-chain campaign, not a single product flaw — no CVE, no vendor patch. The “fix” is operational: avoid/delete affected clones (IoC list at SafeDep), grep before opening, rotate exposed credentials, contain editor/agent auto-run for third-party repos, and review .claude//.gemini//.cursor//.vscode/ as executable code.
Conclusion
Miasma is familiar at the fundamentals — stolen token, credential sweep, self-propagation are known from Shai-Hulud, the binding.gyp wave and IronWorm. What's new is the mouth: the worm followed the developer from the package manager into the editor. The unsettling part is not the dropper's sophistication but how banal the trigger is — opening a third-party repo to read it, the safest gesture in a developer's day. For me the lesson continues the last weeks: one layer of protection is not enough, and --ignore-scripts catches no SessionStart hook. Anyone using AI coding agents must treat them as executing supply-chain actors, review their configuration directories and contain auto-run for third-party repos. Because the incident is ongoing, the SafeDep source governs the repo list, not a snapshot. Don't dramatise — but check today who opened what.
Before the next opened repo harvests your cloud keys — let's talk about your agent hygiene.
I check, mitigate and validate your AI-coding-agent and editor supply chain — from the clone-hygiene check to auto-run hardening.
Sweep over local and CI clones for the Miasma footprint, clone-hygiene checks before opening, rotation of exposed cloud/CI/AI credentials, containment of editor/agent auto-run (VS Code Workspace Trust, SessionStart hook policy, Cursor rule review) and inclusion of .claude//.gemini//.cursor//.vscode/ in your diff and review policy.
Platform operations instead of advice-on-paper: I check, mitigate and validate production developer workflows — from clone hygiene through auto-run hardening to credential rotation.
Programming since 2002 – self-taught, set up my own business with KO-Web in 2012. Over 100 projects, with a focus on security, performance, automation and quality. Today freelance: DevSecOps consulting, training and software development.