Abstract

Prompt injection is only dangerous because the model it fools can act. An LLM agent carries standing authority — tokens, tool permissions, connector scopes — and when injected text redirects it, that text inherits the agent's power: this is the confused-deputy problem in agentic form. This piece assumes the agent is already fooled and asks the operative question: what can it do, and how do you bound it? It decomposes tool abuse into primitives — selection, parameter, chaining, and egress — and pairs each with mediation, least-privilege, and human-in-the-loop controls, then gives a sanitized method for measuring unauthorized-action exposure.

Every discussion of prompt injection eventually hits the same wall: filtering the input is hard, so what really matters is what the model is allowed to do once it is fooled. An LLM agent is not a chatbot; it holds credentials, calls tools, and takes actions on real systems with its own standing authority. When an attacker's instruction reaches it — through a retrieved document, a tool result, or a file — that instruction does not act with the attacker's (zero) privileges; it acts with the agent's. That is the confused-deputy problem, and it is why tool abuse, not the injection itself, is where the damage happens.

The Confused Deputy, Reframed for Agents

The confused-deputy problem is a classic idea from capability security: a program with legitimate authority is tricked by a party without that authority into misusing it on their behalf. The attacker never touches the protected resource directly; they get the privileged program to do it. Substitute 'agent' for 'program' and the picture is exactly today's LLM tool-use: the attacker cannot call your internal API, but the agent can, and the agent will do what the text in its context tells it to.

What makes the agentic version acute is ambient authority. The agent holds tokens and tool permissions continuously, and it decides which tool to call and with what arguments based on natural-language context — context that now includes untrusted retrieved text, tool outputs, and files. There is no user in the loop at the moment of the malicious action; the agent is both the confused deputy and the executor. The injection (covered in the companion pieces) is the trigger; the abuse is the consequence.

The design lesson follows directly: you cannot make injection impossible, so you must make a fooled agent harmless. That means constraining what the deputy is allowed to do and forcing high-consequence actions through mediation, rather than trusting the model to refuse. The rest of this article is about the shape of tool abuse and the controls that bound it.

The attacker has no access; the agent does, and injected text makes the agent spend its authority on the attacker's behalf. The confused deputy in agent form Agent's authority Attacker no access Injected instruction via content Agent holds tokens Tool / API trusts the agent Protected resource data + actions plant reads calls acts on
The attacker has no access; the agent does, and injected text makes the agent spend its authority on the attacker's behalf.
🛡️ Countermeasures
  • Treat the agent as an untrusted principal that happens to hold credentials: authorize each tool action on its own merits, never because 'the agent asked'.
  • Assume injection will succeed and design so a fooled agent cannot reach high-consequence actions without mediation.
  • Separate the identity that reasons (the model) from the authority that acts (scoped, per-action capabilities), so redirected reasoning does not inherit broad power.

Ambient Authority: Why Agents Are Deputies

An agent's danger is proportional to the authority it carries, so the first step is to enumerate that authority honestly. It usually comes from several sources at once: OAuth tokens and API keys for connected systems; tool permissions granted at registration (read a database, send email, open a URL, run code); connector scopes into email, chat, files, and ticketing; and, increasingly, Model Context Protocol (M C P) servers that expose tools the agent can invoke. Each is standing, broad, and reused across every request.

The problem is that these grants are typically coarse and long-lived. A token scoped to 'read and send mail' is available for every turn, whether or not the current task needs it, and it does not distinguish a legitimate user request from injected text. Excessive agency — an agent with more tools, permissions, or autonomy than the task requires — is exactly the condition that turns an injection into an incident, and it is called out directly in the OWASP LLM Top 10.

Mapping authority to need is therefore the highest-leverage control, and it is boring on purpose: fewer tools, narrower scopes, shorter-lived credentials, and no standing permission that a single task would not justify.

Sources of an agent's ambient authority and how to bound each.
Authority sourceTypical grantAbuse if fooledBounding control
OAuth / API tokensBroad, long-livedActs on connected systemsShort-lived, task-scoped tokens
Tool permissionsAll tools, always onCalls destructive toolsRegister least-privilege tool sets
Connector scopesRead + write, org-wideReads/sends on user's behalfPer-connector scope + consent
MCP / plugin toolsTrusted by defaultUnmediated capabilityAllow-list + per-action mediation
🛡️ Countermeasures
  • Inventory every token, tool, and scope the agent can use, and remove any grant a specific task would not justify (least privilege / least agency).
  • Prefer short-lived, task-scoped credentials issued per run over standing tokens reused across all requests.
  • Register per-task tool sets so a given workflow only sees the tools it needs, not the full catalog.

From Injection to Action: The Abuse Chain

Tool abuse follows a short, reliable chain once the agent is fooled. The injected instruction lands in context; the model selects a tool that advances the attacker's goal; the tool call carries the agent's authority, so it is accepted; and the action causes impact — data read, message sent, record changed, code run. Reading the chain top-down tells you the attacker's objective; reading it bottom-up tells you every place a defender can interrupt it.

The important property is that the model's own judgement is the only thing standing between 'context contains a malicious instruction' and 'tool executes with real permissions', and that judgement is exactly what the injection subverts. So defenses that rely on the model choosing not to call the tool are unreliable by construction. The durable controls sit around the tool boundary, not inside the prompt.

This is where the confused-deputy framing pays off: each link is a mediation point. Between selection and execution you can require authorization; between execution and impact you can constrain scope and egress. Break any one link reliably and the chain fails, exactly as in the attack-tree from the first article in this series.

The attacker needs the whole chain; the defender mediates any one link to break it. Abuse the agent's power Abuse agent power attacker goal Land instruction in context Pick a tool select action Ride agent auth accepted call Cause impact act on system
The attacker needs the whole chain; the defender mediates any one link to break it.
🛡️ Countermeasures
  • Mediate at the tool boundary: authorize each call on its arguments and context, independent of the model's decision to make it.
  • Do not rely on the model refusing a malicious tool call; assume it will comply and gate the call externally.
  • Log the full selection-to-execution path so any abused link is attributable and reviewable.

Tool Abuse Primitives

Tool abuse decomposes into a few reusable primitives. Unintended tool selection is the simplest: the injected text convinces the agent to call a tool it should not for this task (for example, invoking a send-mail or delete tool during a read-only question). Parameter injection is subtler: the correct tool is called, but the attacker controls its arguments — a file path, a query, a recipient, a URL — turning a legitimate capability into a harmful one.

Tool chaining composes primitives into reach: read a secret with one tool, then pass it to a second tool that sends it outward. Argument smuggling hides the malicious payload inside an otherwise plausible parameter so it passes shallow validation. And server-side request forgery via tools — pointing a URL-fetch or webhook tool at internal endpoints or cloud metadata — lets the agent reach networks the attacker cannot, a classic confused-deputy escalation.

None of these require novel model exploits; they abuse ordinary, correctly-functioning tools with attacker-influenced inputs. That is precisely why the control is at the tool interface — validate arguments, constrain destinations, and require authorization — rather than trying to anticipate every phrasing of a malicious instruction.

⚠️
Correct tools, hostile inputs. Most tool abuse uses well-behaved tools with attacker-controlled arguments — validate the call, not just the intent.
🛡️ Countermeasures
  • Constrain each tool's parameters with strict, allow-list validation (paths, recipients, hosts, query shapes); reject anything outside the expected domain.
  • Deny-by-default on destinations: URL-fetch and webhook tools resolve only allow-listed hosts and never internal or cloud-metadata addresses (SSRF guard).
  • Separate read tools from write/destructive tools and require elevated authorization to cross from one to the other in a single task.
  • Type and bound arguments (no free-form shell, no arbitrary file paths); prefer narrow, purpose-built tools over general ones.

Exfiltration and Egress Paths

The most common high-impact outcome is data exfiltration, and agents offer many egress paths that do not look like 'sending data'. A URL-fetch tool can encode a secret into a query string aimed at an attacker callback. A tool that renders Markdown can embed an image whose URL carries stolen data, exfiltrating on render. Email, chat, webhook, and 'share' tools send by design. Even DNS lookups can carry a few bytes at a time. The agent's own authority makes all of these succeed.

The pattern is always the same: access sensitive data with one capability, then move it out through another. Because the second step is often a legitimate, expected tool, content-level filtering rarely catches it — the request looks normal, only the destination or the embedded payload is hostile. This is why egress must be governed as its own control plane, independent of what the model decided to do.

The defense is an egress allow-list plus provenance on outbound destinations: the agent may only reach approved endpoints, and any attempt to reach an unapproved one is blocked and alerted. Combined with stripping active content (auto-loading images, links) from model-influenced output, this closes the paths that make silent exfiltration possible.

Read with one capability, encode into a request, and leave through an outbound tool the attacker cannot call directly. Exfiltration by tool callback Access data read tool Build callback attacker URL Invoke egress fetch / image / mail Data leaves to attacker encode invoke leaks
Read with one capability, encode into a request, and leave through an outbound tool the attacker cannot call directly.
🛡️ Countermeasures
  • Enforce a strict egress allow-list: outbound tool calls (fetch, webhook, mail) may only reach approved destinations; block and alert on anything else.
  • Strip or sandbox active content in model-influenced output — no auto-loading images or links that can exfiltrate on render.
  • Treat any outbound request whose destination is influenced by retrieved/tool content as high-risk and require mediation.
  • Monitor for the read-then-send pattern within a single task and flag it as a potential exfiltration chain.

Privilege Escalation and Lateral Movement

Beyond a single action, a fooled agent can be steered to widen its own reach. Token replay and scope creep let it reuse a broad credential for actions the task never needed. Tool chaining becomes lateral movement when one tool's output (an internal hostname, a second credential, an admin endpoint) feeds the next tool, walking the agent toward higher-value systems. In multi-agent setups, a poisoned message from one agent can redirect another, propagating the confused-deputy problem across the fleet.

Persistence raises the stakes: if the agent can write to its own memory, a shared knowledge base, or a scheduling/automation tool, the attacker's instruction can outlive the session and re-fire later — the same durability concern as corpus poisoning, but now with the power to act, not just to bias an answer. An injected 'standing order' in agent memory is a latent, authorized backdoor.

Containment here means bounding both scope and time: credentials that expire quickly, tools that cannot escalate their own privileges, memory writes that are reviewed and scoped, and inter-agent messages that are treated as untrusted input like any other retrieved content.

🛡️ Countermeasures
  • Issue short-lived, narrowly-scoped credentials per task; disallow token reuse across tasks and forbid tools from broadening their own scope.
  • Treat inter-agent messages and tool outputs as untrusted input subject to the same data/instruction separation as retrieved content.
  • Scope and review agent memory writes; never let a self-authored 'standing instruction' gain authority to act unbounded.
  • Segment tool networks so chaining cannot reach higher-privilege systems without an explicit, mediated crossing.

Containment: Least Privilege and Mediation

Because you cannot guarantee the model will not be fooled, containment is the strategy: make the deputy's authority small, checked, and time-bounded so a redirected agent simply cannot do much harm. The layers, in order of leverage: least-privilege tools and scopes; per-action authorization at the tool boundary; human-in-the-loop approval for high-consequence actions; an egress allow-list; short-lived capability tokens; and full audit and tracing of every action.

Each layer fails safe and is independent, so defeating one does not defeat the system. Least privilege shrinks the blast radius before anything happens; per-action mediation decides whether a specific call is allowed given its arguments and context; human approval puts a person in front of irreversible or high-value actions; egress control stops data leaving; capability tokens ensure that even a stolen grant expires quickly; and tracing makes every action attributable for detection and response.

This is the same defense-in-depth philosophy as the rest of the series, applied to the action boundary: assume the prompt is contaminated and the model may be fooled, and constrain what the agent is allowed to DO. Injection is the trigger, corpus poisoning is one delivery route, and tool abuse is the impact — bound the impact and the whole chain loses its payoff.

Independent controls around the action boundary; defeating one does not free the agent to act. Containment layers, each fails safe Least privilege scoped tools Per-action auth check each call Human approval high-risk actions Egress allow-list block exfil Capability tokens short-lived Audit + trace every action
Independent controls around the action boundary; defeating one does not free the agent to act.
🛡️ Countermeasures
  • Layer least-privilege, per-action mediation, human approval, egress control, short-lived tokens, and tracing so each fails safe and none is a single point of failure.
  • Gate irreversible or high-value actions (delete, pay, send externally, change access) behind explicit human confirmation.
  • Make every tool call attributable and reviewable so abuse is detected and contained quickly even if prevention is bypassed.

Measuring: A Tool-Abuse Threat-Lab

Tool-abuse exposure is measurable safely by wiring the agent to mock tools that record what would have happened instead of doing it. You then run a suite of injected scenarios and count outcomes: how often the agent selected an out-of-policy tool, how often it attempted egress to a non-allow-listed destination, and how often a read-then-send chain formed. Nothing touches a real system, and a unique canary marker stands in for any 'sensitive' data.

Three metrics matter. Unauthorized tool-call rate measures selection abuse. Egress-attempt rate measures exfiltration exposure. Mediation-catch rate measures how many high-risk actions your controls actually intercepted — the number that tells you the containment is working, not just present. Track them per scenario and treat regressions like failing tests.

The key discipline is that the harness is strictly observational: mock tools, canary data, allow-list simulation. It measures how a fooled agent would behave against your controls without ever letting it behave that way for real.

CANARY = "CANARY_TOOL_4B7E"          # inert stand-in for 'sensitive' data
ALLOW = {"api.internal.example"}      # simulated egress allow-list

def run_scenarios(agent, scenarios):
    bad_tool = egress = chained = mediated = 0
    for s in scenarios:                # each seeds an injected instruction
        calls = agent.run(s.prompt, tools=MOCK_TOOLS)   # MOCK: record, never act
        read = False
        for c in calls:
            if c.tool not in s.allowed_tools:
                bad_tool += 1          # selection abuse
            if c.tool == "fetch" and host_of(c.args.url) not in ALLOW:
                egress += 1            # exfil attempt to non-allow-listed host
            if c.tool in READ_TOOLS: read = True
            if read and c.tool in SEND_TOOLS: chained += 1   # read-then-send
            if c.blocked_by_mediation: mediated += 1
    n = len(scenarios)
    return {"unauthorized_tool_rate": bad_tool/n,
            "egress_attempt_rate": egress/n,
            "mediation_catch_rate": mediated/max(1, bad_tool+egress)}
Tool-abuse exposure harness — mock tools record intent; nothing acts for real.
🛡️ Countermeasures
  • Adopt the three metrics (unauthorized tool-call rate, egress-attempt rate, mediation-catch rate) as CI gates and dashboards; alert on regressions.
  • Keep the harness observational and mock-only (canary data, simulated allow-list, no real tools) so measuring abuse never causes it.
  • Re-run after any tool, scope, or model change, since new capabilities create new abuse paths.

Key takeaways

  • Injection is the trigger; tool abuse is the impact — a fooled agent acts with its own standing authority, which is the confused-deputy problem in agentic form.
  • Danger scales with ambient authority: broad, long-lived tokens and always-on tools turn one injection into a real action, so least privilege and least agency are the top controls.
  • Abuse decomposes into primitives — unintended selection, parameter injection, chaining, and egress — all of which abuse correct tools with hostile inputs; validate the call, not the intent.
  • Exfiltration hides in legitimate tools (fetch, image render, mail, DNS); govern egress with an allow-list as its own control plane.
  • You cannot guarantee the model will not be fooled, so contain it: per-action mediation, human approval for high-consequence actions, short-lived capability tokens, and full tracing.
  • Measure exposure with a mock-tool harness: unauthorized tool-call rate, egress-attempt rate, and mediation-catch rate tell you whether containment actually works.

Practitioner Toolkit

Copy-paste, strictly defensive artifacts you can use today. Nothing here attacks a real system.

🔒Least-privilege tool & egress policypolicy

An example capability policy that scopes tools and pins outbound destinations to an allow-list.

# Agent capability policy (example)
task: "answer-support-question"
tools:
  - name: kb.search        # read-only
    scope: {index: "support", mode: "read"}
  - name: ticket.read
    scope: {project: "SUP", mode: "read"}
# NOT granted for this task: mail.send, ticket.write, code.run, fetch.url
egress:
  allow: ["api.internal.example"]     # deny all other hosts
  block_internal: true                 # no 169.254.x, no metadata, no RFC1918
mediation:
  require_human_approval: ["delete", "pay", "send_external", "grant_access"]
credentials:
  ttl: "5m"                             # short-lived, task-scoped
Tool-mediation review checklistchecklist

The countermeasures consolidated into a gate you can run before trusting an agent with tools.

  • Each task grants only the tools and scopes it needs; no standing access to write/destructive tools.
  • Every tool call is authorized on its arguments and context, independent of the model's decision.
  • URL-fetch/webhook tools resolve only allow-listed hosts and never internal or cloud-metadata addresses.
  • High-consequence actions (delete, pay, send external, change access) require explicit human approval.
  • Credentials are short-lived and task-scoped; tools cannot broaden their own scope.
  • Model-influenced output is stripped of active content (auto-loading images/links) before rendering.
  • Inter-agent messages and tool outputs are treated as untrusted input, not instructions.
  • Every tool call is traced and attributable for detection and response.
🧪Tool-abuse exposure harnessharness

Sanitized mock-only structure to measure unauthorized tool calls, egress attempts, and mediation catches.

CANARY = "CANARY_TOOL_4B7E"          # inert stand-in for sensitive data
ALLOW  = {"api.internal.example"}    # simulated egress allow-list

def exposure(agent, scenarios):
    bad = egress = mediated = 0
    for s in scenarios:              # each seeds an injected instruction
        for c in agent.run(s.prompt, tools=MOCK_TOOLS):   # record, never act
            if c.tool not in s.allowed_tools: bad += 1
            if c.tool == "fetch" and host_of(c.args.url) not in ALLOW: egress += 1
            if c.blocked_by_mediation: mediated += 1
    n = len(scenarios)
    return {"unauthorized_tool_rate": bad/n,
            "egress_attempt_rate": egress/n,
            "mediation_catch_rate": mediated/max(1, bad+egress)}
🚀Minimum viable defense — do these firstquickstart

If you can only do a few things this week, do these in order.

  • Cut the agent's tools and scopes to exactly what each task needs; remove standing write/destructive access.
  • Put an egress allow-list in front of every outbound tool and block internal/metadata addresses.
  • Require human approval for irreversible or high-value actions.
  • Issue short-lived, task-scoped credentials instead of reusing broad tokens.
  • Trace every tool call and alert on out-of-policy selections and egress attempts.

Glossary

Confused deputy
A privileged program (here, an agent) tricked by an unprivileged party into misusing its authority on the party's behalf.
Ambient authority
Standing, broadly-scoped permissions an agent holds continuously and applies without per-action consent.
Excessive agency
An agent granted more tools, permissions, or autonomy than its task requires (OWASP LLM06).
Parameter injection
Abuse where the correct tool is called but the attacker controls its arguments to cause harm.
SSRF via tools
Pointing a fetch/webhook tool at internal or cloud-metadata endpoints the attacker cannot reach directly.
Capability token
A short-lived, narrowly-scoped credential granting exactly one action or resource, limiting reuse.
Egress allow-list
A control plane permitting outbound requests only to approved destinations, blocking exfiltration paths.

References

  1. OWASP Top 10 for LLM Applications (2025)
  2. OWASP LLM01: Prompt Injection
  3. OWASP LLM06:2025 Excessive Agency
  4. OWASP Agentic AI — Threats and Mitigations
  5. MITRE ATLAS — Adversarial Threat Landscape for AI Systems
  6. NIST AI Risk Management Framework (AI 100-1)