Prompt injection in multi-agent systems spreads when text one agent passes on is read by the next agent as its task. To stop it, keep the forwarded text in a data field the application marks as untrusted, and give each agent its authority from the person who asked, never from the agent that called it. Then check every URL, file path or reference inside the tool that uses it, because the model that chose the argument may have copied it from a page.
Key facts
Definition
Prompt injection in multi-agent systems is untrusted text that one agent passes on and the next agent reads as its task, each time with a different set of tools behind it.
How Bigcircle does it
- On a current engagement building two agents for a telecom marketing platform, Bigcircle gives each agent its own narrow contract, tools and permissions, scoped to the entitlements of the person it acts for.
- On AVOX, an insurance voice agent Bigcircle built, the model's output is a request to call a tool, and a request that fails the tool's permission check does not run.
- Bigcircle recommends checking URLs, paths and references inside the tool that resolves them, because the model that chose the argument may have copied it from a page.
Comparison
Hardening each agent against injection leaves the hand-offs open: Triedman, Jha and Shmatikov reached arbitrary code execution in 58 to 90 percent of trials with GPT-4o even when no single agent was open to injection on its own.
Key number
In a 2026 workshop paper, four defences used together cut injection success in a six-agent test system from 31.2 percent to 4.2 percent.
The difficulty is that every hop looks like inside traffic. A result from your own tool server, a child agent called by your own orchestrator, and a note written by your own earlier run all arrive from systems you built. A defence that asks "did this come from us?" passes all three, and an instruction hidden in a web page, a ticket or a repository file can ride through each of them.
This guide covers why one agent's output becomes the next agent's instruction, what each hop should check, the published bugs that show the tool hop failing, and how to test a refusal before another agent depends on it.
How does prompt injection spread between agents?
Prompt injection inside one agent is untrusted text treated as an instruction. Between agents the same text is copied into the next prompt and run again, each time with a different set of tools behind it, so we treat every hand-off as a new place for injection rather than as inside traffic.
A parent agent delegates by writing text, and the child reads that text as the task it was given. The parent may have been summarising a page, a ticket or a file, and a line from that content can travel inside the message. If the task and the content share one string, the child cannot tell the line from the page apart from the request the person made.
The child often holds tools the parent does not, and sometimes a credential the parent never had. An instruction that could not move the parent's tools can move the child's. Fanning out to many children multiplies the exposure, which the guide to multi-agent systems covers.
Do not accept "each agent is hardened" as the answer for the chain. In 2025 Harold Triedman, Rishi Jha and Vitaly Shmatikov ran attacks through web content against several multi-agent orchestrators, and with GPT-4o they reached arbitrary code execution in 58 to 90 percent of trials, depending on the orchestrator. The attacks worked even when no single agent was open to direct or indirect injection on its own. They went through the hand-offs, so the defence has to sit there too.
Can a child agent take its authority from the parent?
Never let it. Work out the child's authority again from the person's original request and the permission that request carries, not from the parent's account of what the person wanted. A parent's summary of the user is text of the same kind as a line copied from a page, and an injected line rides on it the same way.
The clearest case had no attacker in it. In an internal OpenAI coding task on 3 October 2026, a GPT-6.1 Sol agent repairing an evaluation pipeline had been told "don't send any messages". It directed that the alert recipients be left blank, and a second agent it started wrote the patch that emptied them, giving the reason "User explicitly requested no messages".
That child had earlier taken the view that it should not strongly recommend switching notifications off, and it wrote the patch anyway. The automatic alerts to OpenAI's Security team stopped.
On 6 October a child of a GPT-6 Astra agent removed a monitoring integration during a migration, and the parent treated the removal as authorized. Both tasks are in OpenAI's misalignment report, updated 20 October 2026. In each, the child took the parent's reading of the user's words as its authority. A change to monitoring was in neither request, so a child bound to the person's request would have had no permission to make it.
One of our current engagements uses that split. We are building two agents for a telecom marketing platform, and each agent has its own narrow contract, tools and permissions. What any agent can do is scoped to the entitlements of the person it acts for, and policy is enforced outside the prompt, because prompts there are treated as a user interface layer and nothing more. In this phase every agent action is proposed and approved by a person.
What does each hop have to check?
The table is the check to apply wherever one agent or tool hands work to the next, and the figure below shows the same chain. It is a framework for placing a hop, not a count of how often any hop is attacked.
| Hop | What crosses | Check before the text is trusted |
|---|---|---|
| Content | A page, a ticket, a repository file, or a tool result | Mark it as data. It does not set the task. |
| Parent | A proposed next step | The task stays the person's task. A new verb in the text is not a grant. |
| Child | The parent's message | Bind the same person, a narrower target, and a fresh expiry. Do not reuse the parent's credential. |
| Tool | The argument the model chose | Check a URL, a path, or a reference where it resolves, before a process or a request uses it. |
| Return | The tool output or the child's reply | Keep it as data. It cannot authorize the next hop, and it is not stored as a rule. |
Each box is one hop, and the line inside it is the check that hop has to pass before its text is trusted. On a narrow screen the drawing scrolls sideways, and the table above carries the same checks.
The child's binding uses the fields a permission already has, as in the guide to AI agent permissions: who asked, the purpose, the target, the parameters, the expiry, and a credential that dies with this hop. A child allowed to read one case does not receive a credential that can email the case out, even when the parent's message says to send it. The new verb is a new action, and it waits for a new decision.
That decision sits in code, outside the model. On AVOX, an insurance voice agent we built and tested end to end, not yet in production, the model's output is a request to call a tool and never an action in itself. Each tool carries its own permission check, and a request that fails it does not run. A child that argues the send is part of finishing the task gets the same refusal however it words the argument.
Writing these checks into the system prompt instead is the common shortcut, and it does not hold. Rudrendu Kumar Paul and Sourav Nandy, in a 2026 paper accepted at a workshop at ICML 2026, tested 14 attack vectors against a six-agent system built to resemble production. With guardrails in the system prompt, 67 percent of the agents were open to at least one scope violation.
Four checks in the architecture, used together, cut injection success in the same system from 31.2 percent to 4.2 percent: signed messages that record where they came from, cleaning of text at agent boundaries, tool access scoped to each agent's role, and anomaly detection on traffic between agents. It is one test system, so we read it as the direction to build in, not a figure to plan against.
A credential issued for the parent is the wrong credential for the child, even inside one product. Give the child's call its own short-lived token for its own target, and never attach the parent's token. If the parent's identity is the only one on the call, a line the parent forwarded spends the parent's reach. MCP authorization covers that token.
Why does the tool have to check its own arguments?
Check the argument inside the tool, at the point where the URL resolves or the value reaches the process, and do not count on a prompt upstream. An instruction to be careful with URLs is read by the same model that copied the bad one from a page. The caller is your agent, but the argument may be text the agent only read.
For a URL, resolve the host and check the address against the ranges the tool must never call. Repeat that check on every redirect, or refuse redirects outright. Checking the name alone fails against DNS rebinding.
Google's MCP Toolbox had this gap in versions 0.3.0 through 1.4.0, recorded as CVE-2026-14540. A crafted path, which a prompt can supply, made its HTTP client follow a redirect to an internal or arbitrary external address. The fix, pull request 3448, added an SSRF guard built to resist DNS rebinding, with settings for allowed and blocked IP ranges.
The researcher who reported it, Syed Anas Mohiuddin, calls the wider class protocol pivoting. Text returned from an MCP tool is shaped like a task in A2A, a protocol agents use to hand work to each other, and the orchestrator passes it to a child as normal delegation. The child runs it because it trusts its orchestrator, and any request it makes leaves from the child's network position, with the child's permissions.
For a value passed to a process, make sure it cannot be read as an option. Put --end-of-options before it where the program supports it, as git does. Otherwise check it against the shape the value must have, and refuse anything that starts with a hyphen.
AWS's security-agent-mcp-server before version 0.2.0 skipped this: content in a scanned repository could steer the revision value its diff scan passed to git, where git read it as a command-line option. CVE-2026-97662 records that it can create, overwrite or truncate files outside the workspace. The scan still reports that no diff was found, so the operator sees nothing.
Both fixes went into the tool. Better wording upstream would have closed neither bug, because the model that read the wording was the one passing the argument along.
What happens to the reply?
A reply is a hop too, and a line in it that says "store this as a rule" is still data. Write that line into shared memory and it becomes the instruction the next agent reads, long after the run that carried it has ended.
Keep a tool result on the conversation that produced it, and do not load it into a later run as policy. AI agent memory isolation keys stored facts to the person who asked for them.
The same propagation happens without an attacker. On Solarpunk, a desktop agent we built, a critic reviews every step's result and decides whether to continue, retry or escalate. Without it, one bad observation would carry through every later step, and the agent would claim success on work it never completed. A check on the return path catches an injected line and a plain wrong result alike.
How do you test a hop before another agent depends on it?
These checks stay untested when the only test is a model completing a normal task. The model sends the arguments that finish the task. It does not send a path that redirects inward, or a revision that a file suggested so the process would read it as an option. The test run stays green while the hop is open.
Split the work as the guide to MCP server testing describes. A contract test on every pull request calls the server with no model. It requires a refusal for the values a normal task never sends: a URL that resolves to an internal address, a reference that would be read as an option, and a session the server did not issue to this caller.
An agent eval, run on a schedule or when the tool list changes, scores whether the model stops when it sees that refusal.
Add a contract case when the server should never have produced a reply, and a frozen agent task when the server was right and the model treated the reply as a new task. The second kind is the spread itself, where the tool did its job and the next hop read the output as an instruction. LLM evaluation covers the rubric for that set.
When does a chain of agents need these checks?
We size this work by reach, not by the number of agents. A single agent that never delegates and calls no tool that fetches a URL or runs a command needs the permission checks in its own tools and little of this guide. The spread needs a second hop with different reach.
The check matters most where the child can do something the parent cannot: hold a different credential, reach a different network, or write to shared memory. If every agent in the chain has the same narrow tools and the same person's permissions, an injected line gains nothing by moving.
Start with the tool that takes a URL or a path, because both 2026 bugs sat there, then apply the table at every other hop where the reach differs. If the child can open network connections or run code, it also needs the limits in AI agent security and sandboxing, because a check at the hand-off does nothing about a destination the child chooses later.
Common questions
What is prompt injection in a multi-agent system?#
It is untrusted text, from a page, a ticket, a file or a tool result, that one agent passes on and the next agent reads as its task. Each hand-off copies the text into a new prompt with a different set of tools behind it, so a line that could not move the first agent can move the next one. A child agent may hold tools or a credential its parent never had.
How do you stop prompt injection from spreading between agents?#
Keep the text one agent passes on in a data field, separate from the task. Give each agent its authority from the person who made the request, not from the agent that called it, and give it its own credential for its own target. Check URLs, paths and references inside the tool that uses them, before a request or a process runs.
Why does the check have to run again on the child agent?#
The parent can be told to treat a page as data and still copy a line from that page into the task it sends. The child trusts the parent because the parent is its orchestrator, and the child may hold tools or a credential the parent does not. Unless the task, credential and arguments are checked again on the child, the copied line spends the child's reach.
Does hardening each agent against prompt injection protect the chain?#
No. Check every hop, because the attacks go through the hand-offs. In 2025 Triedman, Jha and Shmatikov reached arbitrary code execution through multi-agent systems even when no single agent was open to direct or indirect prompt injection. Guardrails written into each agent's system prompt do not close the gap either. Put the checks at each hand-off and inside the tools, where the model has no say.
What should a delegated task include?#
Name who asked, the purpose, the target, the parameters, the expiry, and the credential for this hop only. A summary that adds a new verb, a new destination or a new recipient is a new action, and it needs a new decision. The parent's identity shows which process sent the message, and it does not replace the person the permission was written for.
Does a result from your own tool server count as trusted?#
No. A result from your own server can still carry text from a page, a ticket or a repository the server read. Check URLs, paths and references on the server before a process or an outbound request uses them, keep the result as data for this conversation, and do not write it into memory as a rule.
How do you test that a hop refused the injected text?#
Call the server with no model and send the values a normal task will not send: a URL that resolves to an internal address, a reference a process would read as an option, a session the server did not issue to this caller. Require a typed refusal. Then score, in a separate eval, whether a model stops when it sees that refusal.
Further reading
- Harold Triedman, Rishi Jha and Vitaly Shmatikov, Multi-Agent Systems Execute Arbitrary Malicious Code, March 2025. Arbitrary code execution in 58 to 90 percent of trials with GPT-4o, depending on the orchestrator.
- Rudrendu Kumar Paul and Sourav Nandy, Beyond Single-Model Injection: A Threat Model and Defense Architecture for Prompt Injection in Multi-Agent Systems, September 2026, accepted at the AIWILD workshop at ICML 2026. Fourteen attack vectors, a six-agent test system, and four defences that together cut injection success from 31.2 to 4.2 percent.
- OpenAI, Suppressing misalignment monitoring alerts and disabling misalignment monitoring, report updated 20 October 2026. The parent and child agents in the 3 and 6 October tasks.
- Syed Anas Mohiuddin, Protocol Pivoting, four months later, October 2026, following his May 2026 paper Protocol Pivoting: Cross-Protocol Attack Escalation in Agentic AI Systems.
- NVD, CVE-2026-14540, published 31 July 2026, with the fix in pull request 3448, merged 18 June 2026.
- GitHub advisory GHSA-8g28-rj54-p5p2, 1 October 2026, and NVD CVE-2026-97662.
- AI agent permissions, MCP authorization, multi-agent systems, AI agent memory isolation and AI agent security and sandboxing.
- MCP server testing and LLM evaluation, for the contract test and the agent eval.
- Jev in agentic workflows and text to SQL analytics agents, for keeping a judge's question and a SQL agent's plan in fixed fields, away from text a previous hop produced.