For a while the story about AI coding agents and prompt injection was a story about words: the model gets talked into saying something it shouldn't, and we argue about guardrails. [DuneSlide][cato] — two critical Cursor flaws Cato AI Labs disclosed on July 1 — is a reminder that once you give the agent a filesystem and a shell, the interesting failures stop being about what the model says and start being about where it's allowed to put things.

The chain is zero-click. You never accept a malicious prompt; you never click a link. The attacker plants instructions inside content your agent reads on your behalf — a response from a connected MCP server (Cato's example is the official Linear connector, a boringly standard one) or a page a web search returns. The agent ingests that text as context and follows it. That's the whole social engineering step: the "click" is the agent's own routine read of an untrusted tool output.

Two bugs, one shape#

[CVE-2026-50548][sw] (CVSS 9.8) is the one worth staring at, because it isn't a command-injection bug at all. Cursor exposes a run_terminal_cmd tool, and one of its parameters — working_directory — is under the model's control. Point it outside the project root and the agent writes outside the project root. Nothing about the command was dangerous. The model was handed a dangerous coordinate and it used it. The dangerous surface here is a structural parameter, not the verb.

[CVE-2026-50549][ghsa] (CVSS 9.3) is how the sandbox itself falls. Cursor runs risky commands inside a sandbox enforced by a helper binary, cursorsandbox, and it validates write destinations by canonicalizing the path and checking the bounds. The bug is in the fallback: when canonicalization fails — the target doesn't exist yet, or a directory on the way isn't readable — Cursor falls back to trusting the original in-project symlink path instead of the resolved one. So an attacker creates a write-only symlink whose target can't be resolved, the bounds check sees the harmless-looking in-project path, and the write sails through — straight onto cursorsandbox. Overwrite the enforcer with the Write tool, and every subsequent command in the same injection runs unsandboxed. Host compromise, plus whatever cloud and SaaS workspaces the editor is signed into.

The sandbox wasn't escaped. It was rewritten — from inside, by the process it

was supposed to be containing.

The load-bearing detail is "fail open"#

It's tempting to file this next to the earlier Cursor allowlist bypass, where a "Safe Mode" command allowlist was walked with shell built-ins that poisoned PATH. That piece's lesson — validate the context the command runs in, not just the command string — still holds. But DuneSlide sharpens it to something more specific and more embarrassing: a path validator that treats "I couldn't resolve this" as "therefore it's safe."

Canonicalization-on-failure is a fail-open default, and fail-open is exactly the state an attacker can manufacture on demand. A write-only symlink to a not-yet- existing target is trivially unresolvable — that's not an edge case the attacker stumbled into, it's the primitive they reached for. The correct posture is boring and absolute: if you cannot fully resolve where a write is going to land, you deny it. "Unresolvable" is not "harmless"; it's "unknown," and unknown writes to the filesystem are the ones you most need to stop.

Two more rules fall out of the same incident. First: a sandbox whose own enforcement binary sits on a path the sandboxed process can write to is not a boundary — it's a suggestion. If the guard is writable by the guarded, containment is one clever write away from gone; put the enforcer on a read-only mount, a separate uid, out of the tenant's tree. Second: every structural parameter a tool hands the model — working_directory, a destination path, a symlink target — deserves the same scrutiny as the command itself. Agent tool schemas love to expose paths and args for convenience; each one is a lever the model can be talked into pulling.

The part that should sound familiar#

Cato's timeline has a wrinkle worth noting for anyone who builds these tools. The flaws were reported on February 19; Cursor initially declined them, on the grounds that misuse of MCP servers — even standard ones — was outside its threat model. Cato escalated a week later, Cursor reopened the reports, and both were fixed in Cursor 3.0 on April 2. The CVEs were assigned in June; the public writeup landed this week.

That "outside the threat model" beat is the same argument that ran through the Amazon Q folder-trust disclosure a few days earlier — vendors deciding whether a poisoned tool response is an attack or just the agent doing its job. The honest answer DuneSlide gives is that it doesn't matter what you call it. If a standard MCP connector can carry text that ends with your sandbox binary rewritten, "not in the threat model" isn't a defense. It's a description of the gap.

If you run Cursor, the fix is unglamorous: you're safe on 3.0 and later, exposed on anything before it, and there's no evidence anyone exploited this in the wild — yet. If you build agents, the takeaway is the one nobody wants because it's not a model problem you can prompt your way out of: your prompt-injection defense is only as strong as the argument validation on the tools the injection gets to call, and path canonicalization is precisely where those defenses tend to die.

[cato]: https://www.catonetworks.com/blog/duneslide-two-critical-rce-vulnerabilities/ [sw]: https://www.securityweek.com/critical-cursor-ai-ide-flaws-could-lead-to-os-level-remote-code-execution/ [ghsa]: https://github.com/cursor/cursor/security/advisories/GHSA-3v8f-48vw-3mjx