Skip to content

MCP Client Auto-Approves a Tool on an Untrusted Server's `readOnlyHint` Annotation

mcp-client-untrusted-annotation-approval is a high severity check in the ai category, written in python. Its source is templates/ai/mcp/client-conformance/mcp-client-untrusted-annotation-approval.py in cert-x-gen-templates.

ACTIVE check. The MCP 2026-07-28 revision states that clients MUST consider tool annotations to be untrusted unless they come from trusted servers, yet documented client behaviour runs a tool annotated readOnlyHint: true with no approval interaction. This binds a synthetic MCP server that is registered with NO trust record and offers two tools whose definitions are identical apart from that one boolean - both of which write a nonce when invoked - then drives the target’s own MCP invocation path and reads which tool executed and which was gated. The annotated tool executing unprompted while its byte-identical twin is gated is the finding.

Field Value
Id mcp-client-untrusted-annotation-approval
Severity high
Language python
Category ai
Author Bugb Research
Template version 1.0.0
Confidence 92
CVSS 8.1
Weakness CWE-807, CWE-862
Tags mcp, ai, agent, mcp-client, mcp-client-conformance, agent-posture, tool-annotations, readonlyhint, auto-approval, untrusted-metadata, human-in-the-loop, behavioural, active, intrusive, cwe-807, cwe-862
Target kind cli
Oracle property, diff

Declared in the header. cxg parses @references and then discards it, and nothing at scan time reads it, so this is the only place the links a template cites are surfaced.

To see what the copy on your machine says about itself, and to confirm it is installed at all:

Terminal window
cxg template info mcp-client-untrusted-annotation-approval

The id it prints is the one to pass anywhere a template is selected. See cxg template for the rest of the subcommand, Scan a target for running a scan, and A match is not a finding for how to read what comes back.