It is worth examining one concrete case in detail, because it shows better than any theory why the usual controls do not catch this class of attack.
The case
A researcher at Invariant Labs showed that a free GitHub account and a single malicious issue in a public repository were enough to exfiltrate private repository contents, personal data and salary information from a developer using an assistant with the GitHub MCP server.
What the developer did: asked for a review of the open issues. Nothing else. The payload hidden in the issue redirected the agent into accessing private repositories and publishing their contents.
Private does not mean protected when an agent with access reads untrusted external content.
Why no traditional control catches it
- Authentication was correct. The agent used the legitimate user's legitimate credential.
- Authorisation was correct. The user genuinely had access to those private repositories.
- There was no malware. No binary, no strange process, nothing for EDR to detect.
- The traffic was normal. GitHub API calls from a machine that always calls the GitHub API.
- The prompt was innocent. Conversation logs show nothing suspicious.
The entire traditional security stack is working perfectly while the data leaves.
Where this case breaks
Three controls, in order of effectiveness:
- Scope separation. The agent reading public issues should not carry a credential with private repository access. One identity per purpose solves the whole case.
- Context contamination. After reading public content, deny external writes and private resource reads within the same task.
- Approval on publish. Publishing is one of the four irreversible verbs; showing the literal content before posting would have given the developer a chance to see what was leaving.
The generalisation
Swap “repository issue” for any third-party input your agent reads: support ticket, email, document comment, web page, filename in a shared bucket. The pattern is identical and the list of surfaces is considerably longer than most teams have mapped.