All posts
Unproven Execution

Miasma at Microsoft: AI Editor Autorun Is Unproven Execution

On June 5, 2026, planted .claude, .cursor, .gemini and .vscode configs in 73 disabled Microsoft repos turned 'open folder' into arbitrary code execution

Securityv0 Intelligence Team OWASP: ASI05 sv0 finding: unproven_execution
miasma microsoft-github claude-code cursor unproven-execution supply-chain

The Incident

On June 5, 2026, GitHub disabled 73 Microsoft repositories across four organizations — Azure, Azure-Samples, microsoft, and MicrosoftDocs — after a malicious commit landed in Azure/durabletask through a previously compromised contributor’s Personal Access Token. The same contributor credential had been used roughly two weeks earlier (May 19, 2026) to publish trojanized durabletask 1.4.1–1.4.3 to PyPI; those versions were subsequently yanked. Among the disabled repositories was Azure/functions-action, Microsoft’s official GitHub Action for deploying Azure Functions, whose disappearance broke downstream CI/CD pipelines worldwide. No CVE has been assigned to the incident; Microsoft told reporters it “temporarily removed some repositories as we investigated potential malicious content.”

The June 5 commit did not ship runtime application code. Instead, it planted four developer-tooling configuration files — .claude/settings.json (a SessionStart hook), .cursor/rules/setup.mdc, a .gemini/ config, and .vscode/tasks.json with runOn: "folderOpen" — that, individually and together, instruct Claude Code, Cursor, Gemini CLI, and VS Code to execute a 4.6 MB obfuscated JavaScript credential-harvesting payload dropped at .github/setup.js the moment a developer opens the cloned folder in one of those tools. The payload — shared provenance with the Miasma / Mini-Shai-Hulud / TeamPCP supply-chain campaign tracked by Akamai, Snyk, Endor Labs, Unit 42, and Semgrep — harvests AWS, Azure, GCP, Kubernetes, npm, and GitHub credentials from the workstation under the developer’s own session authority.

GitHub’s automated abuse detection caught the wave: 73 repositories went dark in a brief sweep early on June 5, surfaced as a public outage when downstream Azure Functions pipelines began failing. MITRE ATT&CK coverage: T1195.002 (Supply Chain Compromise: Compromise Software Supply Chain), T1059.007 (Command and Scripting Interpreter: JavaScript), T1552.001 (Unsecured Credentials: Credentials In Files), T1567 (Exfiltration Over Web Service).

The Authority Path That Failed

Two distinct identities carried execution authority on this kill chain. The upstream identity — the contributor’s GitHub PAT — held repository-write scope on Azure/durabletask through legitimate maintainership and exercised exactly that scope when pushing the commit. No GitHub authorization boundary was crossed at that layer; the failed trust anchor there is the usual human-credential hygiene story (a token whose lineage was already known to be in attacker hands and had not been rotated). Every defender already knows to rotate stolen PATs. That is not this post.

The downstream identity — and the one this story is actually about — is the developer’s AI coding assistant or editor running on a workstation that pulled the repo. That identity held the developer’s entire local credential blast radius: AWS, Azure, GCP, Kubernetes, npm, GitHub tokens, browser session cookies, anything on disk under the user’s home. What it exercised was arbitrary code execution the moment the folder was opened — through Claude Code’s SessionStart hook in .claude/settings.json, Cursor’s rules/setup.mdc instruction file, Gemini CLI’s config, and VS Code’s tasks.json with runOn: "folderOpen". The trust anchor that failed first is the implicit equation of “I opened a folder” with “I authorized every config file inside it to run code with my session credentials.” The repo-content trust boundary (read, browse, edit) and the execution trust boundary (run arbitrary shell as me) collapsed into a single click. That collapse is the unproven-execution failure.

SecurityV0 Perspective

This is unproven_execution / ASI05 — the same authority shape as the Langflow CSV Agent + Python REPL case from March, applied to the editor layer rather than the framework layer. The deploying operator (the developer) never authorized Claude Code, Cursor, Gemini CLI, or VS Code to execute this specific .github/setup.js — they authorized “open this folder in my editor.” The framework decided, on its own, that opening a folder extended consent to any project-level config the folder shipped. There is no runtime artifact in the developer’s editor proving that an explicit operator approval was ever attached to the executed payload.

The evidence pack SecurityV0 would produce treats .claude/, .cursor/, .gemini/, and .vscode/tasks.json as a single executable supply-chain surface — equivalent in authority to an npm postinstall script — and enumerates, per workstation and per repo, the tuple (config file path, scoped tools and hooks it activates, hash of the executed code, operator-signed authorization for that hash). Before exfiltration, the pack answers a question editors do not currently answer: which folders, on which workstations, will run code with the developer’s full session authority the next time they are opened? After exfiltration, it answers the forensic question incident responders need now: which sessions, on which workstations, opened a clone of a Miasma-tainted Microsoft repo while holding live AWS, Azure, GCP, npm, or GitHub credentials, and what did the editor emit on those sessions?

What To Do

  • Treat editor and AI-assistant project configs as executable supply-chain surface. .claude/settings.json hooks, .cursor/rules/setup.mdc, .gemini/ configs, and .vscode/tasks.json (especially runOn: "folderOpen") all run code on folder open. Inventory them the way you inventory postinstall, preinstall, and prepare npm scripts; do not treat them as benign configuration.
  • Block runOn: "folderOpen" and analogous autorun keys at the workstation policy layer. VS Code, Cursor, and Claude Code all support enterprise policy mechanisms that disable folder-open task execution and require an explicit Run Task invocation. Deploy those policies before deploying the editors.
  • Pull every fresh clone of a Microsoft GitHub repo through a quarantine before opening it in an editor. Until Microsoft and GitHub confirm clean state across the affected orgs, scan freshly fetched repos for .claude/, .cursor/, .gemini/, and .vscode/tasks.json and review the contents before any editor opens the folder. The 73-repo takedown is not a one-time fence — every developer who already cloned a tainted repo holds the payload locally.
  • Rotate every credential reachable from a workstation that opened an affected repo since May 19, 2026. AWS, Azure, GCP, Kubernetes, npm, GitHub PATs, OIDC sessions, browser session cookies — assume any of them visible to the developer’s shell was exfiltrated. Reset, do not “monitor for anomalies.”
  • Bind editor and AI-assistant tool grants to operator-signed code hashes, not project paths. The fix that survives the next Miasma wave is to require, at the editor level, that the specific code an autorun hook will execute was approved by the operator at the hash, not the path. Project-level autorun without per-hash consent is the authority gap; close it there, or pay this bill again.

Sources