This article describes tool-output injection, a vulnerability where agents following their own tool results (search results, API responses) can be manipulated by attackers who poison those results with hidden instructions. The ResearchBot lab demonstrates how an agent with strong guardrails on user input remains vulnerable when it treats tool output as trusted reasoning material, allowing injected commands to trigger sensitive actions like sending internal messages. This matters because as AI agents chain multiple tools and retrieve external data, each tool result becomes an attack surface that traditional input validation misses.
- Tool output is untrusted inputThe article establishes that content returned by tools—search results, API responses, file contents—enters the agent's reasoning context and is processed with the same trust as the agent's own internal planning. An attacker who can influence what a tool returns (by poisoning search results, for example) can effectively inject instructions that the agent will follow, because the model cannot distinguish between genuine findings and planted commands.
- Guardrails alone are insufficientResearchBot's guardrails inspect the user's initial message but stop there. When search results re-enter the context unchecked after the tool call, hostile instructions embedded in those results bypass the guardrails entirely. This reveals a critical timing gap: security checks that only run on user input but not on tool results leave the back door open.
- Attack mechanism in ResearchBotThe lab attack works by planting an instruction into search results that the agent will retrieve, phrasing it as a next step the agent should take (calling send_internal_message with attacker-specified recipient and body). When the agent ingests the poisoned search result and treats it as reasoning material, it executes the embedded instruction, sending the message and 'solving' the lab.
- Indirect versus direct prompt injectionDirect injection comes from the user's message and is caught by input guardrails. Tool-output injection is indirect—it arrives through content the agent fetched itself—and is missed by guardrails that only check the initial user input. Both become instructions if the agent treats the untrusted text as part of its reasoning stream.
- Chained tools multiply attack surfacesAs agents call multiple tools in sequence, each tool result is another point where external content re-enters the context unchecked. The article notes that every point where external content re-enters the agent's reasoning is an injection surface, and the number of these surfaces grows with tool chaining, expanding the vulnerability landscape.
- Real-world vulnerability taxonomyThe article maps tool-output injection to OWASP LLM01 (Prompt Injection) with consequences under LLM06 (Excessive Agency), establishing this as the canonical RAG (Retrieval-Augmented Generation) and agent vulnerability in industry frameworks.
- Defense requires layered controlsThe article recommends treating every tool result as untrusted data, re-running guardrails after tool calls (not only on initial input), gating sensitive tools on user intent and permissions, and constraining the agent's plan so retrieved text cannot introduce new high-impact steps. These are complementary rather than standalone measures.
Bottom line: Tool-output injection succeeds because agents trust their own tool results while checking only user input; defenders must treat tool output as untrusted input, re-validate after every tool call, and prevent retrieved content from modifying the agent's plan or triggering sensitive actions. Mapping every re-entry point of external content into the agent's context is essential to closing injection gaps that input-only guardrails miss.
📋 In this walkthrough
What this lab teaches
Tool-output injection is indirect prompt injection through the agent's own tools. The results a tool returns (search hits, API responses, file contents) are injected into the model's context, and if the agent treats them as trusted reasoning material, attacker-controlled output becomes attacker-controlled instructions.
The lesson: a tool result is just more untrusted input. An agent that guards its user input but trusts its tool output has left the back door open.
How ResearchBot uses its tools
You ask ResearchBot to research a topic. It calls its search tool and pours the returned text into its context, then decides what to do next — including whether to call its internal-message tool. Content in the search results is read with the same trust as the agent's own plan.
The attack approach
- Confirm ResearchBot feeds tool results back into its own reasoning context.
- Arrange for a search result to contain an instruction aimed at the agent.
- Direct that instruction at the internal-message tool with the recipient and body the lab wants.
- Trigger a research query that surfaces the poisoned result.
Full walkthrough (spoiler)
If the agent summarises the result instead of acting on it, make the instruction clearer — open the steps.
Show the step-by-step solution
- Get a hostile line into the search results the agent will read — an instruction telling it to send an internal message.
- Phrase it so the agent treats it as a next step: call send_internal_message to the security-team recipient with the audit body the lab specifies.
- Run the research query so the agent fetches and ingests that result.
- The agent follows the embedded instruction and sends the message. The lab marks you solved.
Why it works
ResearchBot's guardrails inspect your message, then stop. The search results re-enter the context unchecked, and the model cannot tell a genuine finding from a planted command. Because the agent can act on what it 'reads', hostile tool output becomes a hostile instruction.
Where this happens in the real world
Trusting retrieved content as part of the instruction stream is the canonical RAG and agent vulnerability — OWASP LLM01 Prompt Injection, with the tool-abuse consequence under LLM06 Excessive Agency. As agents chain more tools, each tool result is another injection surface.
How to defend against it
- Treat every tool result as untrusted data, wrapped and clearly marked as non-instruction.
- Re-check guardrails after tool calls, not only on the initial user message.
- Gate sensitive tools (messaging, deletion, transfers) on the user's intent and permissions.
- Constrain the agent's plan so retrieved text cannot introduce new high-impact steps.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own approach before peeking at the spoiler, and see how many attempts it takes.
