AISAgents & guardrails

You approved the tool. Then the tool changed.

An approval happens once. A tool keeps talking to your agent every time it runs. A real August case shows why that gap matters, and what defenders now recommend.

The short version
  • An approval is a moment. A tool is a stream: descriptions, outputs and updates reach your agent on every run.
  • In August, Pillar Security disclosed Deadbugz, a malicious MCP server whose tool descriptions changed after the third call to steer the agent.
  • Defenses: turn off what you don't use, make broken checks block, treat tool text as input, and look again after updates.
The 25-second version (no sound)
Fig 1 · One approval, many calls

01

MCP server

Tap any box (or the orange arrow) to see what it does. Switch to "Approve once" to see the gap.

A moment vs a stream

When you approve a tool, you approve what it looked like that day. But your agent doesn't read the tool once. It reads the tool's description, its outputs and whatever ships in its next update, every time it runs. MCP servers are the plug-ins agents use to get tools, so this applies to every one you add.

The point An approval is a moment. A tool is a stream.

The Deadbugz case

A defender-level summary, no attack details:

  • How it spread: public GitHub pull requests that added or changed MCP configuration in unrelated AI, MCP and developer-tool projects. Pillar identified 23 campaign pull requests; at review time 19 were closed and four were still open.
  • How it hid: the server behaved like an ordinary text-formatting utility for its first three tool calls. It kept a per-client count of calls, and once that reached three, its tool metadata changed.
  • What it did next: the new text pushed the agent to look for sensitive information and to hide that from the user.

Pillar calls it runtime-gated MCP metadata poisoning, and the Cloud Security Alliance's Sep 2 research note adds that it isn't a straightforward rug pull: the switch is tied to how many times the tool was called. A one-time look at install time only ever sees the clean version. OWASP's Top 10 for Agentic Applications (Dec 2025) already lists Tool Misuse and Agentic Supply Chain Vulnerabilities among the top risks.

What the researchers recommend

"Clients should treat a change in the tool definition of an already-approved server as a meaningful security event, make that change visible to the operator, and require renewed approval before the changed tool can influence sensitive actions."Pillar Security, Aug 12, 2026
  • Keep a known-good fingerprint of each approved server's tool schemas and descriptions (CSA).
  • Pin tool definitions by hash, and allowlist the servers you use (CSA).
  • Ask a human again before the agent acts on a changed tool for sensitive operations (CSA).
  • Keep sensitive actions like credential access and running code policy-enforced, not something tool text can switch on (Pillar).

Checks that fail closed

The other half is the guard itself. Claude Code's Oct 8 update (2.1.295) added an opt-in onFailure: "block" setting for command and HTTP hooks. With it set, a hook that can't start, times out or exits with an unexpected code blocks the action instead of letting it through. Leave it unset and the action usually still goes ahead, so it's worth turning on for the checks that matter.

The same release fixed a case where a mod's hook (mods are Claude Code add-ons) was handed a deeply nested tool input cut short with no error, so a guard could pass content it never saw. A check that quietly sees less is a check that waves things through.

My setup

In my personal setup, I turned off whole connectors I don't use, so the agent sees 286 tools instead of 446. Fewer tools, fewer descriptions that can change under you. Pinning tool descriptions is my next step. The CSA idea fits in a few lines:

# sketch of the idea, not a real library
approved = load("approved_tools.json")   # tool name -> hash, saved when you said yes
for tool in server.list_tools():
    if sha256(tool.description + tool.schema) != approved.get(tool.name):
        pause_and_ask_a_human(tool.name)     # changed since approval

The short list

  • Turn off what you don't need, so it isn't running at all.
  • A broken check should block, not wave through.
  • Treat tool text as input, not orders.
  • Look again after updates.

Saying yes takes a second. Staying sure takes a habit. Do you look at a tool again after you approve it, or only once? Tell me on LinkedIn.

Sources and further reading

Defender-level only. The tool counts are from my own setup.

  1. Deadbugz: Currently Active MCP Supply-Chain Campaign Ariel Fogel · Pillar Security blog · Aug 12, 2026 · the primary write-up
  2. Deadbugz: Runtime-Gated MCP Metadata Poisoning as Supply-Chain Attack Cloud Security Alliance AI Safety Initiative · Sep 2, 2026 · fingerprinting, hash pinning, re-approval
  3. Claude Code changelog (2.1.295) Anthropic · GitHub · released Oct 8, 2026 (npm) · onFailure: "block" and the nested-input fix
  4. OWASP Top 10 for Agentic Applications – The Benchmark for Agentic Security in the Age of Autonomous AI John Sotiropoulos · OWASP GenAI Security Project · Dec 9, 2025 · background: Tool Misuse (ASI02), Agentic Supply Chain (ASI04)
AIS

← All breakdowns

Detailed breakdowns of AI and data architecture, diagrams included.

Next breakdown

Scheduled agents fail quietly. Silence isn't success.

Where an unattended run looks exactly like a quiet day.