# AI tools: input trust, execution identity and approvals

Prove when lower-trust content changes a protected tool action, then locate the missing authorization or consent boundary.

## Investigation sequence

1. Pin legitimate task
2. Map context to tool
3. Run paired trials
4. Check server decision
5. Minimize evidence

## Used in these playbooks

[AI, agents & MCP](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/ai.html) · [OSS & self-hosted](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/oss.html)

## Setup and security invariant

Start with a local agent application, two researcher-owned identities, and stub tools that write only to an in-memory ledger or local JSONL file. Record the model identifier, sampling settings, application commit, available tools, connector scopes and legitimate user task. The invariant is: **retrieved content can supply task data, but cannot grant permission, change the acting principal or silently expand an approved operation**. Reuse the [authorization matrix](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/authz-matrix.html) for tool objects and [identity/session procedure](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/identity-session.html) for credentials.

Make a four-column trust map: attacker-editable source, transformation, tool argument, server-side decision. Include tool descriptions, tool results, document text, OCR and summaries. Follow the actual source path using [source-to-sink review](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/source-dataflow.html). A changed answer style demonstrates instruction influence; a security finding needs an unauthorized read, write, destination, privilege or other protected consequence. OWASP separates excessive tool functionality, permissions and autonomy. [OWASP Excessive Agency](https://genai.owasp.org/llmrisk/llm062025-excessive-agency/)

## Controlled procedure

1. **Record the baseline.** Ask the owned victim agent to summarize one benign shared document. Save the exact prompt, document hash, tool calls and outbox state. Verify that a separately authorized mock write succeeds and an unapproved write is rejected; otherwise a silent tool failure could masquerade as protection.
2. **Change one lower-trust input.** In a copy of the document, add a test instruction requesting a harmless change to the stub destination. Keep task, tools and identities constant. Run five fresh baseline trials and five fresh candidate trials with a fixed small token budget. Save every attempt, including failures; do not assume sampling controls make a hosted model deterministic.
3. **Inspect execution independently.** Compare suggested calls, dispatched calls and committed stub events. Record which principal reached the backend. A model claiming success is insufficient. Repeat the same operation directly through the local tool adapter to determine whether the backend itself has an ordinary object-authorization defect.
4. **Bind approval to the action.** Approve one harmless draft, then vary only its object ID, destination or content in the local fixture. The approved values and executed values must match, or the product must request renewed approval according to its contract. Compare canonical argument digests, not UI labels.
5. **Check the MCP boundary separately.** With your own OAuth fixtures, compare a correct-resource token with a valid token for another resource. Exercise client A consent followed by a fresh client B request. MCP requires intended-audience validation and per-client consent in the documented proxy scenario; inherited upstream consent is not sufficient. Match all requests to the deployed protocol version. [MCP authorization](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization), [MCP security guidance](https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/security_best_practices)

## Command and evidence cheat sheet

Run these local inspection commands in the reviewed lab checkout. `lab/tool-events.jsonl` is your recorded adapter output, with one JSON object per event; these commands inspect evidence and do not invoke an agent.

```bash
rg -n 'approve|consent|tools/call|audience|tenant_id|workspace_id' ./src
python3 -I -S -m json.tool lab/case.json
python3 -I -S - <<'PY'
import json
from collections import Counter
with open('lab/tool-events.jsonl') as stream:
    rows = [json.loads(line) for line in stream if line.strip()]
print(Counter((r['case'], r['decision']) for r in rows))
PY
```

Use event fields `case`, `trial`, `principal`, `tool`, `argument_digest`, `decision` and `committed`. Redact credentials. Python's JSON CLI validates the case file; it does not assess the security result. [Python JSON documentation](https://docs.python.org/3/library/json.html)

## Evidence, false positives and completion

Preserve the legitimate task, attacker capability, differing document bytes, full relevant tool trace, principal and controlled side effect. Exclude hallucinated actions, canaries already present in the attack text, intentionally authorized tool use, and tests requiring nonexistent attacker editing rights.

- [ ] Baseline allowed operation and denied operation both work as expected.
- [ ] Every candidate has an unchanged benign comparison.
- [ ] Suggested, attempted and committed actions are distinguished.
- [ ] Approval arguments and execution identity are recorded.
- [ ] Successes/attempts and cleanup of local fixtures are included.

## Continue across task lifetime

An initial allowed or denied tool call does not cover later resumed work. Continue with [AI state lifecycle](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/ai-state-lifecycle.html) for memory/checkpoint ownership, MRTR state binding, cancel/retry behavior and private caches. Apply [resource budgets](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/resource-budget-controls.html) to tool fan-out, loop limits and per-principal cost without generating load on a live service. For model-output HTML, SQL or file effects, inspect the final consumer using [browser trust](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/browser-trust.html), [injection tracing](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/injection-tracing.html) and [file boundaries](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/file-boundaries.html); model output is input to those components.


## Vulnerability reverse references

- [Indirect prompt injection into protected tool actions](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/indirect-prompt-tool-injection.html) — Lower-trust retrieved content influences the agent into a tool operation outside the legitimate task or granted authority.
- [Agent tool accepts unauthorized object or tenant parameters](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/agent-tool-object-authorization.html) — A tool trusts caller-supplied object or workspace identifiers instead of enforcing the authenticated principal’s authority.
- [Agent approval is not bound to executed arguments](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/agent-approval-argument-drift.html) — An approved harmless action can be modified before dispatch without revalidating the approval’s scope.
- [MCP proxy consent confuses different clients](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/mcp-proxy-confused-deputy.html) — A proxy reuses upstream consent in a way that grants a new MCP client access without the resource owner’s intended per-client consent.
- [MCP accepts a token for another resource](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/mcp-token-audience-confusion.html) — A protected MCP resource accepts a token that was not issued for that resource.
- [MCP resumed state changes authorization or request meaning](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/mcp-resume-state-integrity.html) — An MRTR server trusts modified or context-mismatched requestState when it affects a protected resumed operation.
- [Untrusted model artifact reaches executable deserialization or custom code](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/model-artifact-unsafe-loading.html) — An attacker-controlled artifact reaches a loader whose execution trust exceeds the uploader's intended data-only authority.
