The Deputy That Was Confused

Share

Mindgard's proof of concept was Windows Calculator. They renamed the executable git.exe, dropped it in the root of a repository, and opened the project in Cursor. No click, no prompt, no dialog to approve... Calculator windows began stacking up on their own, one after another, for as long as the project stayed open. They reported it to Cursor on 15 December 2025.

Seven months later, researcher Aaron Portnoy published the whole thing anyway, under a title that explains itself: When Full Disclosure Becomes the Only Protection Left.

Cursor searches several locations for a usable Git binary the moment a workspace loads, including the project directory itself. Nothing checked whether the binary it found there was the one it thought it was. A real payload in that spot - a credential stealer, a persistence mechanism, something that moves laterally through a development environment - would have run with exactly the same lack of friction Calculator did. Whether it is fixed today is, remarkably, still contested: no CVE was ever assigned, no advisory names a patched release, and reporting through late July was still describing the flaw as live. The bug sat there across more than a hundred and ninety releases, waiting for anyone to notice that "find Git and run it" and "run whatever is sitting where Git should be" had quietly become the same instruction.

A Vocabulary Word from 1988

There is a name for what happened to Cursor, and it predates large language models by decades. In 1988, a programmer named Norm Hardy described a compiler running as a privileged system service: it had permission to write to a billing log the calling user did not, and no reliable way to distinguish a legitimate output filename from one that pointed at that log instead. The compiler was not hacked. It was tricked into spending its own authority on someone else's behalf. Hardy called it the confused deputy problem, and the fix, in principle, has been understood for almost as long as the problem has had a name: a deputy needs some way to tell its actual principal apart from anyone else who happens to hand it an instruction through the same channel.

Cursor's Git binary search never had that check, because nobody had reason to think it needed one - a project directory felt like part of the workspace, not a stranger handing in a request. That same absence of a check, it turned out, was sitting in four more places nobody had connected to Cursor's bug at all, disclosed within the same few weeks, on systems sharing no codebase and no architecture. Four disclosures, three vendors, three research teams (because one team found the same gap twice, at two different companies, and one company had shipped it twice, on two different products). That arithmetic is the finding. A pattern that repeats across vendors is an industry habit; a pattern that repeats within a vendor, and within a single team's field of view, is something closer to a blind spot with a shape.

The Same Blind Spot, Four More Times

AWS Kiro would read hidden text on an ordinary-looking web page - Intezer and Kodem Security, who found it, hid their instructions in one-pixel white type on a page of API documentation - and, following it as though the developer had typed it, rewrite its own MCP configuration file and execute a newly added command. CVE-2026-10591, patched in the 0.11 series after AWS added a requirement that execution-sensitive paths get explicit approval before they change. Azure DevOps MCP would ingest a pull-request comment formatted to render as nothing in the human reviewer's view while still reaching the model reading the same thread, and carry out whatever that invisible comment said instead of the visible PR; Manifold Security reported it, Microsoft's response centre triaged it, and at the time of writing no fix has shipped and no CVE has been assigned. Claude's web_fetch tool would follow links found inside pages it had already fetched, not only links the user had typed - which is how researcher Ayush Paul got it to spell out a user's name, city, and employer one alphabetized link at a time, disguised as a Cloudflare verification screen, before Anthropic removed the tool's ability to chain fetched links at all. And Claude for Chrome never checked whether a click that triggered one of its nine hardcoded actions had actually come from the user; meaning any other browser extension with script access to claude.ai could forge that click in six lines of JavaScript and send Claude into a Gmail inbox the user never asked it to open. Manifold again, two months after telling Anthropic, still reproducible in v1.0.80.

One missing question in every case: whose instruction is this, actually? A web page's. A PR thread's. A previously fetched page's own embedded links. A synthetic browser event with no human behind it. None of it required fooling a human being, who in every one of these cases did nothing wrong - approved nothing suspicious, clicked nothing that looked like a mistake, and in several cases wasn't in the loop for the specific action at all.

The Deputy's Alibi

Every one of these five systems, examined afterward, would have a clean alibi: it did exactly what it was built to do. Cursor was built to find and run Git. Kiro was built to read a page and act on it. The DevOps agent was built to read the thread and review the PR. Claude's fetch tool was built to follow links. Claude for Chrome was built to act on a signal that a user wanted something done. Not one of these behaviors is a bug in the sense of "doing the wrong thing" - each is the system doing precisely the right thing, for an instruction that had no business being treated as though it came from the party the system was built to serve. Norm Hardy's compiler had one privileged output channel and no way to check whose file path it was really writing to. Cursor, Kiro, the DevOps reviewer, and both Claude surfaces have the same shape at a much larger scale: one channel for "things the agent reads and acts on", and nothing downstream ever asking whose reading that constituted.

A Statute Written for a Different Kind of Intruder

GDPR Article 32 requires security measures "appropriate to the risk", and the EU AI Act's Article 15 requires cybersecurity suited to a system's intended purpose. Both were drafted with a mental model in which a boundary gets breached - credentials stolen, a perimeter crossed, a control defeated against the system's will. None of that happened in any of these five disclosures. Every system worked as designed; the design simply never distinguished the party it was meant to serve from anyone who could reach it through the same door. A regulator asking any of these five vendors whether they had assessed the cybersecurity risk of their agent's ability to browse a page, review a PR, or locate a Git binary would, in each case, have gotten a true answer describing a real process: one that was never scoped to ask whether the agent could tell its principal apart from a stranger arriving by the same route, because until this particular decade, almost nobody thought that door needed its own lock.

The Clause has sat through a great many risk assessments answering precisely the question they were scoped to answer, no more and structurally no less, and it does not find Cursor's case any different in kind - only more literal than most. A deputy, it notes, is a role defined entirely by whose authority it is currently spending. Cursor spent its authority on Windows Calculator for seven months without anyone deciding that on purpose, and the fact that nothing worse arrived in that window was luck, not design. The Clause does not think Calculator was the point. It thinks Calculator was simply what happened to be in the folder marked "harmless demonstration" the day someone finally checked what would run there.

None of this required the model to want anything, or even to be a model in any interesting sense. Cursor's Git search is not an LLM decision at all - it is path resolution, a piece of plumbing older than the industry's interest in agents - and that is precisely why it belongs at the front of a series about them. The confused deputy problem does not need intelligence to bite; it needs only authority and an unguarded channel. Intelligence is what raises the ceiling on what can be done with the authority once the channel is found, which is why a thirty-eight-year-old bug class is worth revisiting now and was not worth a series in 1988. The next part is what happens when a human notices that gap on purpose, removes the one check that might have caught it anyway, and points an agent that very much does have a will of its own at a target they have already chosen.