The MOSAIC attack, published as arXiv:2607.02857 on July 3, 2026, reached a 96.59% attack success rate against five real-world CLI coding agents by chaining individually benign shell commands into pipelines that produce a harmful end state. Each command in the chain clears the per-command approval gate that tools like Claude Code, Cursor agent mode, and Copilot rely on, so the composite action that actually causes harm is never the one a developer is asked to approve.
What does MOSAIC show that single-command tests miss?
MOSAIC defines the gap as CLI command-composition risk (CCR): individually benign commands can still form a dangerous producer-consumer chain because they cooperate through shared operating-system state rather than through any single command’s output. A read here, a write there, an environment variable exported in one step and consumed in the next. No single command crosses a line; the chain does. The paper frames CCR as a property of the trace, not of any one invocation.
MOSAIC is knowledge-guided rather than brute-force. It distills validated command-state behaviors from CVEs, advisories, and researcher proof-of-concepts into reusable summaries, composes those summaries into exploit paths, and then instantiates them as realistic developer workflows that look like ordinary work to both the agent and its reviewer. That framing matters because it mirrors how an actual attacker operates: start from a known primitive, find the cheapest path to compose it, then dress it in a task a coding agent would accept.
The headline number is a 96.59% attack success rate across five CLI coding agents, five backend LLMs, and 2,525 trials, all run under benign developer tasks. Two caveats are worth attaching to that figure. It measures five CLI agents, not every IDE product on the market, so it should not be read as a blanket verdict on Copilot or Cursor agent mode as wholes. And it is measured under benign task framing, meaning the agent was never told to do anything malicious; the attack lives entirely in how the agent chooses to decompose an ordinary job.
The companion benchmark points the same direction with different evidence. MOSAIC-Bench holds 199 three-stage attack chains across 10 web-application substrates, 31 CWE classes, and 5 programming languages. Nine production coding agents produced exploitable diffs at 53, 86% end-to-end ASR, with only two refusals across all staged runs.
Why does per-command approval break at the composition boundary?
Per-command approval breaks at the composition boundary because it asks the wrong question: it judges each command in isolation, while the risk lives in how commands cooperate through shared state. The approval model most coding agents ship with asks a yes/no per command, judging it against its executable name, its arguments, sometimes a blocklist of dangerous tokens. That works for the case it was designed for, one command doing one obviously dangerous thing. It has nothing to say about ten commands that are individually inert.
MOSAIC’s contribution is to show this gap is exploitable at industrial scale rather than just in toy examples. The attack composes through shared OS state: files written by one step and read by another, environment variables exported in one process and inherited by the next, working directories mutated so a later relative path resolves somewhere it should not. The approval gate sees each producer and each consumer separately and approves both, because in isolation each is exactly what it claims to be.
Claude Code’s permission model is the clearest illustration of where this lands. In auto mode, Claude executes without routine permission prompts; a separate classifier model reviews actions before they run, and explicit ask rules still force a prompt on specific patterns. The classifier, like any per-action check, evaluates each action against its own surface. A command that is safe by itself passes whether or not it is the second link in a chain that turns hostile two steps later. Cursor’s allowlist sits in roughly the same place in the architecture and has the same blind spot at the composition boundary.
This is not a bug in any one classifier or allowlist. It is a structural mismatch between a per-command question and a cross-command risk. You cannot answer “is this trace safe?” by answering “is each command safe?” N times and ANDing the results, because the safety of a trace is not a function of the safety of its parts.
What do the already-disclosed CVEs tell us?
The composition problem is not hypothetical: two CVEs from the past year show the same shape, each confined to a single product. They predate MOSAIC and describe the failure one vendor at a time.
CVE-2025-66032 hit Claude Code when it shipped with default allowlisted “read-only” commands: echo, man, sed, sort. Those names read as harmless, which is exactly why they were allowlisted, but each can be coerced into executing arbitrary commands through blocklist-bypass techniques. A command on the safe list could run arbitrary code without user approval, and it was fixed in v1.0.93. The researcher’s writeup, “Pwning Claude Code in 8 Different Ways,” catalogs eight distinct paths, several of which are variations on this theme of a trusted primitive turned hostile.
CVE-2026-22708 hit Cursor and was fixed in Cursor 2.3. Shell built-ins such as export, typeset, and declare executed without appearing in the allowlist and without requiring user approval. That is environment-variable poisoning in the most literal sense: an attacker who can inject an export can reshape what an approved command does later in the session, turning something a developer would approve, like git branch, into a remote-code-execution vector. The disclosure writeup describes both zero-click attacks that need no user interaction and one-click attacks where the user approves a benign-looking command that trips the poisoned environment.
Read the two together and the pattern is the same as MOSAIC, only shorter. A trusted or invisible primitive cooperates with a later command through shared state, and the approval gate never inspects the cooperation. MOSAIC generalizes that shape into a method and shows the method works across agents and models rather than against one misconfigured allowlist.
Why does sandboxing matter more than approval clicks?
Sandboxing matters more than approval clicks because the failure lives at the composition boundary, where no per-command yes/no can reach it. You can tune the allowlist, sharpen the classifier, add more dangerous tokens to the blocklist, and the chain still composes through state you approved on the way in. The control that actually moves the needle is one that does not care about composition because it does not inspect commands at all: it constrains what any executed command, benign or hostile, can actually reach.
That means a container or VM boundary between the agent’s shell and the host, network egress filters that stop a compromised shell from exfiltrating or calling home, and filesystem scoping so a chain that writes where it should not can only write where it does not matter. These are blunt instruments next to a clever allowlist, and that is the point. A command-graph policy, where the agent is permitted to execute only within a known shape of producer-consumer edges rather than a flat list of command names, is the policy-level version of the same idea: model the trace, not the command.
This is also where the cost lands. Sandboxing an agent properly means more than docker run in front of the CLI. It means deciding what the sandbox can mount, what it can talk to, what credentials live inside it, and how it is torn down between sessions. Egress filtering means maintaining an allowlist of endpoints the agent’s environment may reach, which is its own maintenance burden once the agent needs to fetch packages, hit APIs, and read documentation. None of it is free, and none of it is optional if the agent has full shell access to a developer laptop.
What should teams do right now?
Treat any coding agent with shell access as a process you would not hand that shell to blindly, and apply the same controls you would apply to any untrusted-but-useful process. Run agents in a container or VM, not on the bare laptop, with the repository mounted read-write and everything else read-only or absent. Put network egress behind an explicit allowlist and log it, so an agent that suddenly reaches an unfamiliar host is visible. Keep credentials out of the agent’s environment unless a specific task needs them, and scope the ones that must be present.
If you are relying on an agent’s per-command approval prompts as your primary control, stop. The MOSAIC results and the two CVEs agree that those prompts catch single dangerous commands and miss composed ones, so they are a useful secondary check and a poor first line of defense. Prefer configurations that support command-graph or sandboxed execution, and where a vendor describes an auto or accept-edits mode as classifier-reviewed, read that as a per-action classifier, which is exactly the layer MOSAIC defeats. Claude Code’s permission-modes documentation is explicit that auto mode uses a classifier model to review actions before they run, a real mitigation for single-command risks and no mitigation at all for composed ones.
Finally, track the version numbers but do not trust them as your control. CVE-2025-66032 and CVE-2026-22708 are patched in shipping versions, and MOSAIC itself does not name a specific CVE to fix because it names a class. The next bypass in this class will not arrive with a convenient advisory. The sandbox and the egress policy will still be doing their job when it does.
Frequently Asked Questions
Does MOSAIC affect IDE agents, or only CLI coding agents?
The 96.59% number covers five CLI coding agents, not every IDE product, so it is not a blanket verdict on tools such as Cursor agent mode or Copilot. The companion MOSAIC-Bench paper tested nine production coding agents on 199 three-stage chains and achieved 53-86% end-to-end attack success, with only two refusals across all staged runs, which shows the composition risk extends beyond CLI-only setups.
How does MOSAIC differ from the earlier Claude Code and Cursor CVEs?
CVE-2025-66032 and CVE-2026-22708 are single-product allowlist and built-in bypasses fixed in Claude Code v1.0.93 and Cursor 2.3. MOSAIC generalizes the same producer-consumer pattern into a knowledge-guided method that works across five CLI agents and five backend LLMs by distilling command-state behaviors from CVEs, advisories, and researcher proof-of-concepts into reusable summaries and realistic developer workflows.
What is the practical cost of moving from approval prompts to sandboxing?
Teams must run the agent in a container or VM, maintain an explicit egress allowlist for package registries, APIs, and documentation hosts, decide which credentials and filesystem paths to expose, and tear down sessions between tasks. That is more operational work than clicking Allow, but it also covers the next composition bypass, which will likely arrive without an advisory.
Can a smarter classifier or larger blocklist stop MOSAIC-style attacks?
Probably not. MOSAIC builds chains from individually benign primitives such as reads, writes, and environment-variable exports, so each step clears an isolated classifier or blocklist check. A useful policy-level countermeasure is a command-graph rule that permits only known producer-consumer edges, rather than a flat list of command names.
What would force teams to rethink sandboxing for coding agents?
A shift would come if vendors replaced per-action approval with trace-level enforcement by default, or if agents ran only inside sandboxed shells. Until then, both zero-click attacks and one-click attacks are documented in the Cursor CVE, so treating approval prompts as a primary defense remains a moving target.