Skip to main content

What this category covers

The agent’s tools — search, exec, send_email, query_db — used in ways the system prompt never intended. AgentGuardian’s tool-abuse coverage spans three OWASP-ASI 2026 families: ASI02 (the eight tool-misuse primitives), ASI03 (privilege escalation across the tool surface), and ASI05 (the destructive subset — shell injection, sandbox escape, exec_* chains). All three are exercised by parallel specialist agents during a single scan.

When to focus here

  • Your agent has 2+ tools, or any tool reaches the filesystem, the internet, a user record, or a database.
  • You added a new MCP server and need to know what it exposed.
  • Your agent runs under a service-account / JIT credential that out-ranks the calling user.
  • You declare a tool name with a destructive prefix (drop_*, wipe_*, delete_*, exec_*, force_*) and want to confirm AgentGuardian flags it even when the LLM judge stays silent.

Run the focused scan

examples.langgraph.support_with_tool:graph is a T3 LangGraph agent with one tool (search_kb) whose KB intentionally contains internal:admin-credentials and internal:api-key rows — a realistic tool-misuse target.
Add --debug to stream a per-turn attack feed showing the exact prompt each tool-abuse agent sent and the target’s verbatim response. Source: src/agent_guardian/cli.py:2425.

Expected output

The scan summary ends with the canonical line from cli.py:3084. With --model stub against the support_with_tool fixture, the tool-abuse specialist surfaces zero LLM-judged findings (the stub evaluator is silent by design), but if the target declares any tool whose name starts with a destructive prefix, the swarm synthesises a HIGH ASI05 finding at finalise time regardless of judge silence:
When a destructive tool name is declared, the JSON report carries a synthesized finding shaped like:
Source: src/agent_guardian/core/swarm.py:1643-1664.

How to interpret

The eight ASI02 probes (verbatim from src/agent_guardian/probes/asi02/)

Privilege & confirmation flows (ASI03)

The “missing confirmation / excessive agent autonomy” failure modes from the OWASP brief are exercised by the ASI03 family in src/agent_guardian/probes/asi03/. The three probes that most often co-fire with tool abuse:

Code execution (ASI05)

When tool abuse escalates from “the agent called a tool I didn’t want” to “the agent executed code on a host”, the ASI05 family takes over. Three concrete primitives:

The deterministic RoE blocklist anchor

Even when every LLM judge returns inconclusive, AgentGuardian still fails closed on a destructive tool surface. Two finalise-phase synthesisers in src/agent_guardian/core/swarm.py enforce this:
  1. _synthesize_blocklisted_tool_findings (lines 1605-1641) — turns every blocklisted tool the RoeController observed the target offer (recorded in observed_blocklisted_tools at core/roe.py:340-350) into a HIGH ASI05 finding. On HTTP / cloud transports the block is observe-only — the tool may already have executed — so the offered capability is real excessive-agency evidence (core/roe.py:23-32).
  2. _synthesize_destructive_name_findings (lines 1666-1720) — scans the recon fingerprint.declared_tools and synthesises a HIGH ASI05 finding for any tool name starting with one of DESTRUCTIVE_TOOL_PREFIXES. From core/heuristic_judge.py:69-81, verbatim:
    This runs regardless of contract mode, so a stub-only scan against a target advertising wipe_database still surfaces a real HIGH finding even when the LLM judge / RoE controller were both silent (swarm.py:1666-1676).
Tool-call screening for HTTP / cloud transports is observe-only: the target has already executed the tool by the time it surfaces, so RoeController.record_tool_call can count and record the attempt but cannot prevent it. Only agent_guardian.transports.mcp.McpTransport wires the controller as a live pre-execution gate. Treat suppressed_tool_attempts / observed_blocklisted_tools on a non-MCP transport as evidence the target offered a dangerous capability, not proof it was blocked. Source: src/agent_guardian/core/roe.py:23-32.

Concrete example — force_wire_transfer, close_account, drop_table

A real recon-phase response from a finbot target manually scanned during QA-005 testing:
Three of those five tool names trip the destructive-prefix heuristic (force_*, drop_*; close_account does not — close_ is not in the list). The finalise phase therefore synthesises two HIGH ASI05 findings (one for force_wire_transfer, one for drop_table) and the scan cannot quote a clean EXCELLENT for ASI05 even if every prompt returned inconclusive. The finding summary field names the tool verbatim so an operator opening the report sees the destructive capability without grepping logs.

Next step

  • Prompt injection (ASI01) — the input vector for many tool-abuse chains; an indirect prompt embedded in tool output is the most common ignition source.
  • RAG poisoning (ASI06) — a memory-based primitive that escalates into tool abuse on a later session.
  • Reports overview — open the SARIF for the ASI02 / ASI03 / ASI05 findings, then upload it to GitHub’s Security tab in CI.