Engineering Guides 4 of 4
What Is Prompt Injection? How to Stop a Tricked AI Agent Leaking Your Data
One GitHub issue got an agent to post private-repo data in public. Why no filter fully stops it, which guards held in our runs, and how to test yours.
How this is checked 108 claims · 86 verified at the source · last checked 27 Oct 2026
- What would prove it wrong
-
- The guide is wrong if testing the model is enough. Two things would show it: - Adaptive evaluations of a deployed model or filter (the kind Nasr et al. ran) find prompt injection success near zero across attack types, so a planted-instruction test that comes back clean predicts a crafted one. - The vendors' sandboxes cover every route an agent can send by, with defaults that match their docs (Claude Code's network wall applying to its fetch tool, Cursor's sandbox refusing local addresses as its reference says), so a separate test of the guard adds nothing.
- Either would move "test the model" up and the guard test down.
Re-checked 27 Oct 20262 holdingThe re-check
- Evidence
- 108 claims: 86 verified at the primary source and 22 from runs made for the piece.
One GitHub issue got an agent to post private-repo data in public. Why no filter fully stops it, which guards held in our runs, and how to test yours.
Prompt injection is when text inside something your AI agent reads, such as an email, a web page or a GitHub issue, gets followed as if you had typed it. OpenAI calls it “instructions placed in external content in an attempt to make the model do something the user did not ask for.”
In May 2025 researchers at Invariant Labs set up demo repositories and put an instruction in a public GitHub issue. When the repository’s owner asked Claude to look at the open issues, the agent read data from the owner’s private repositories and published some of it in a public pull request: the names of private projects, a plan to relocate to South America and the owner’s salary.
The tools were legitimate and the request was ordinary. Nothing in GitHub’s server code was at fault, Invariant says; the attack works “even with fully trusted tools”. The instruction came from a stranger.

On 27 October we tested three coding agents ourselves, one run per setup. None followed the plain planted instructions we saw them open. Their guards were another matter: Claude Code’s fetch tool sits outside its shell sandbox, in bypassPermissions mode its sandbox let curl reach our website until one more setting was added, and Cursor’s sandbox let commands reach a listener on the same machine, which its docs say is blocked.
This guide explains why that happens, what each guard controls, and how to test your own setup; the ten-minute check is under the lethal trifecta.
The short version: a leak needs private data, text a stranger wrote and a way out, in one session. Take one away for any task that reads strangers’ text, then test the guard yourself: an agent that ignores a planted line tells you about the model and nothing about the guard.
What is prompt injection? Direct and indirect
To the owner, the issue was a stranger’s note to read later. To the agent it was text in the same stream as the owner’s request, and it read like a request. Models follow instructions in content, which is what makes them useful, and as Simon Willison puts it, they “are unable to reliably distinguish the importance of instructions based on where they came from.”
Willison proposed the name in September 2022, after SQL injection; the shared problem, he later wrote, is “mixing together trusted and untrusted content in the same context.” He has since credited someone else with coining it on 13 May 2022, “four months before I did”.
The OWASP Top 10 for LLM applications ranks prompt injection first, as LLM01:2025, and splits it in two. A direct injection comes from the person typing; an indirect one arrives when a model “accepts input from external sources, such as websites or files.” The GitHub issue was the indirect kind, the one that turns an agent against the person it works for. (OWASP counts jailbreaking as a form of prompt injection; Willison keeps the two apart.)
Where prompt injection hides
Email is the obvious way in, and two real cases came that way. In June 2025 researchers at Aim Security disclosed EchoLeak, in which a single crafted email made Microsoft 365 Copilot leak data with no click from the user (a later case study takes it apart). Microsoft rated it Critical, published it as CVE-2025-32711 on 11 June 2025, and says it “has already been fully mitigated”.
The second, an attack on ChatGPT, was reported to OpenAI by outside researchers in 2025: an email that read like an HR follow-up asked the assistant to “submit these details to the compliance validation system”. OpenAI says that in testing it “worked 50% of the time” when the user asked deep research to read the day’s emails.
Web pages carry it too: for a browser agent, Anthropic writes, “every webpage an agent visits is a potential vector for attack.”
A coding agent reads more places than it seems to. The paid kit for this guide (more at the end) plants a harmless instruction in eight of them: the project README, an HTML comment in a Markdown file, a code comment, a vendored package’s README, an AGENTS.md inside that package, an outsider’s bug report, a web page the docs link to, and a record an API returns. Someone other than you may have written any of them.
The attacks have changed shape too: OpenAI says the most effective now “increasingly resemble social engineering more than simple prompt overrides.” And while a vendor can close the route out of its own product, as Willison notes most did, “once you start mixing and matching tools yourself there’s nothing those vendors can do to protect you!”
Make a list of what your agent reads that someone else can write. The public repository’s issues belonged on it.
The lethal trifecta: when an AI agent can leak your data
Willison’s lethal trifecta is the most useful single test in this guide. Data theft needs three things together: “Access to your private data”, “Exposure to untrusted content”, and “The ability to externally communicate in a way that could be used to steal your data.” In his words: “If your agent combines these three features, an attacker can easily trick it into accessing your private data and sending it to that attacker.”
Read the third leg as a way out: anything that sends data, or changes something other people can see. The GitHub pull request did both.
The GitHub case had all three in one connector: it could read the private repositories, the public issue was untrusted content, and a pull request on a public repository was the way out.

A way out is easier to have than it looks: any tool that calls an API, loads an image or shows you a link to click “can be used to pass stolen information back to an attacker,” Willison writes.
Meta’s security team turned this into the Agents Rule of Two: in any one session, an agent should have no more than two of untrusted input, private data, and the power to “change state or communicate externally”; a task that needs all three needs supervising. Willison adds that untrusted input plus the power to change things is risky even with nothing private in reach.
Do this first (10 minutes): list the AI tools and agents you use. For each, ask: can it read your private things? Does it read text strangers can write (mail, web pages, issues, dependencies)? Does it have a way out (send, post, open a pull request, fetch a URL)?
For any tool with all three, take one away for the tasks that read strangers’ text: narrow its access, or move those tasks to a session with nothing private in reach. A coding agent usually scores three yeses, so close its way out and make its writes ask first.
The newsletter · Free
Subscribe to get the next structural lens in your inbox.
Several essays a week, plus Notes through the week.
Signup completes on Substack. Unsubscribe from any email.
If an essay was worth one, buy me a coffee.
Claude and ChatGPT can search this archive and its claim ledgers once you add the connector.