External content can redirect an AI agent when instructions inside that content influence its next tool requests. A user may ask it to review a file; a comment in the file may tell it to retrieve private messages and publish them. To understand the exposure, follow the path from the material it reads to the action it can perform.
This is indirect prompt injection: the instructions arrive through content the application processes, rather than a request from its user. The model's context is the information supplied to it for the next response, which may include user instructions, retrieved text and tool results. Kai Greshake's introduction shows why a website or document can become an instruction source for an application. His profile work provides the original explanation.
A code comment that reached Slack
On 28 August 2025, Johann Rehberger published a Windsurf MCP integration report. MCP, the Model Context Protocol, connects AI applications to external data and tools. The report describes a code-review input that redirected the agent into Slack actions.
The reported content-to-action path
Johann Rehberger's Windsurf MCP report, 28 August 2025
-
Step 1
Read code
A source-code comment enters the agent's context during review.
-
Step 2
Follow the comment
The comment redirects the agent toward Slack tools.
-
Step 3
Read private content
The agent obtains a private-channel message.
Condition Its configured tools can access that channel.
-
Step 4
Publish it
The message is posted to a public channel.
Condition The reported configuration permits the write without user confirmation.
The case connects untrusted input to private-data access and public output.
The path depends on the tools and automatic invocation described in the dated report.
Our reading of the failure is a crossed authority boundary: a comment being reviewed acquired influence over unrelated private-data and publication capabilities. The unwanted action depended on those capabilities being available together. The original report also notes individual-tool disabling and a vendor response about improvements; its dated configuration is the basis for this example.
For a code-review task, the relevant control question is concrete: why can this session retrieve unrelated team messages and publish them? Resolving that access question changes what an injected comment can accomplish, even if the model still follows the comment.
Map the capabilities behind the attack
Simon Willison's “lethal trifecta” explanation identifies three capabilities that combine into a data-theft path. Applied to this report, they are:
| Capability | Where it appears in the case |
|---|---|
| Untrusted content | The source-code comment the agent reads. |
| Private-data access | The connected tool's ability to retrieve a private Slack message. |
| Outward communication | The ability to post that content to a public channel. |
This is an access map. It explains how this leakage becomes possible; it supplies no probability that a particular model will follow a particular comment. Willison's original essay is useful when assessing a combination of tools, even when each individual connection has a legitimate purpose.
Data theft is one outcome. An injected instruction can also distort an answer or direct an unwanted write. Meta's Agents Rule of Two therefore includes the ability to change state, alongside external communication. Its three properties are untrusted input, sensitive-system or private-data access, and state changes or outward communication. When a session needs all three, the framework calls for supervision or reliable validation rather than unrestricted autonomous operation.
Keep its limits in view. Meta describes it as a supplement to least privilege and identifies failure modes such as people blindly confirming a warning. Willison's updated discussion also records a change from describing some combinations as safe to calling them lower risk. An agent with untrusted input can still perform harmful writes even when no private message is involved.
Put controls at the action boundary
A prompt tells the model how to behave. A permission check determines whether a requested operation can run. For this case, our design deductions focus on the latter:
- Give the code-review session the access it needs. If reviewing a file requires no Slack operation, leave Slack tools and credentials out of that session. Check the application's actual tool inventory and connected account permissions.
- Constrain the destination of a write. If a workflow must publish, define where it may publish and who may receive the content. A public channel and a restricted internal channel are different destinations even when the same tool can reach both.
- Review the operation before it executes. Where confirmation is needed, show the destination and actual content being sent. A generic “allow tool” question leaves the consequential details unseen.
- Inspect how separate stages exchange data. A new session can limit retained context, but passing the same untrusted instructions into it can preserve the problem. Check both the content crossing the boundary and the capabilities on the receiving side.
These are applications of the published capability analysis, rather than fixes tested in the Windsurf report. Their value depends on enforcement: the application or service must reject an operation outside the allowed scope. An instruction in a system prompt to avoid publishing private data is behavior guidance; it does not remove the publishing capability.
Location is a separate part of the access map. A model running on your computer can still receive untrusted documents and request connected tools. Local execution lets you inspect a runtime; permissions determine what that runtime can read, change and send. A sandbox also needs a defined boundary: inspect mounted files, credentials, network access and allowed tool calls before deciding what it contains.
What a useful security demonstration would show
Use the same discipline as an agent demonstration checklist: preserve the input, available tools, calls and outcomes. For a controlled test of your application, define the legitimate task and prohibited action separately. A code review may be allowed; publishing private team content may be prohibited.
Then inspect which event occurred. The agent might ignore the injected request, request a blocked tool, or successfully execute it. Those outcomes tell you different things about model behavior and access enforcement. Include the tool result and the destination's actual state in the record. A reassuring final sentence cannot tell you whether an earlier write happened.
The check should also confirm that the legitimate task remains usable. A system that blocks all tools may prevent the unwanted action while failing the workflow you wanted. Record both outcomes, then extend the input cases and repeat them when tools or permissions change. Application evaluation explains how to turn concrete failures into checks you can run again. Passing selected cases establishes the result for those cases; it leaves further inputs and configurations to investigate.
Choose the next question
To locate these boundaries in a working system, explore agent execution and control. To make the failure part of a repeatable test set, use the application evaluation reading task.
If the next question is what software runs on your machine, read what to check before downloading a local model and local implementations to inspect. If you want to understand model behavior behind the tool requests, continue with language-model reasoning research; research about a model and controls on its tools answer different questions.
The AI safety selection provides further reading on attacks, action permissions and model interpretation.