第十五章:Tool Protocol 安全¶
15.1 先划信任边界¶
MCP 和 A2A 都让不受模型控制的数据、描述和动作进入 Agent 链路。协议可互操作,不等于对端、工具描述或参数可信。
%%{init: {"flowchart": {"nodeSpacing": 12, "rankSpacing": 18, "padding": 8}}}%%
flowchart TB
U["用户"] --> H["Host / 调用方"]
H --> M["模型"]
H --> P["MCP 或 A2A 对端"]
P --> X["外部系统"]
H --> A["审批与审计"]
Host/调用方应是策略执行点:验证身份和来源、限制工具与数据、审批高风险动作、记录可追溯证据。不要让模型文本、Agent Card 或工具 description 自行决定权限。
15.2 OAuth 2.1、PKCE 与 audience¶
MCP 授权能力在协议中是 OPTIONAL;采用该授权规范的受保护 HTTP Server 是 OAuth Resource Server,Client 是 OAuth Client。stdio 不套用这套 HTTP 授权发现流程,而由环境或受控配置提供凭据。A2A 可声明 OAuth,也支持其他 security scheme,不能一概要求 OAuth。
2026-07-28 MCP 规范引用的是 OAuth 2.1 IETF draft-13,不是已发布 RFC;Client ID Metadata Documents 同样引用草案。RFC 9728(受保护资源元数据)、RFC 8707(资源指示符)等则是已发布 RFC。这里陈述的是 MCP 引用版本,不声称这些草案是 IETF 截至今日的最新修订。
| 控制项 | 要求 |
|---|---|
| Authorization Code + PKCE | 公共客户端使用 Authorization Code 流程与 PKCE(S256);不要用隐式流程或把 client secret 放进桌面/浏览器应用。 |
| 精确 redirect URI | 按规范精确匹配登记的回调 URI;原生应用 loopback 端口有 RFC 8252 定义的例外,不能扩展成任意通配符。 |
| audience/resource | 授权请求和 token 请求都指定 RFC 8707 resource;资源服务器验证令牌目标、issuer、有效期、scope 和对象权限。JWT 验签,opaque token 按相应 introspection/服务端机制验证。 |
| 最小 scope | 令牌只授予当前用户、当前 Server 和当前操作所需权限;读写、项目和租户要分开。 |
| 刷新与撤销 | 短生命周期 access token;保护 refresh token,并支持撤销、轮换和异常会话失效。 |
audience 检查防止“拿给 A 的 token 调 B”。仅验证签名或 scope 不够:令牌必须是为当前资源服务器签发的。
授权发现从受保护资源元数据找到授权服务器,再读取其 OAuth/OIDC 元数据。发现出来的 URL 仍要做 SSRF 和来源校验。当前 MCP 推荐支持 Client ID Metadata Documents,动态客户端注册 DCR 已弃用但保留兼容;凭据按 issuer 隔离,issuer 变化时不能复用旧 client secret。授权响应带 iss 时必须和预先记录的 issuer 比较;对端声明会提供却缺失时应拒绝。
15.2.1 禁止 token passthrough¶
Client 将为目标 MCP Server 签发的 access token 发给该 Server 是正常用法。被禁止的 token passthrough 是:MCP Server 接受并使用本来发给其他服务的 token,或把收到的 token 不加校验地转交下游 API。Server 访问下游需建立独立授权关系,使用面向下游的凭据;token exchange 只有相关系统明确支持时才可采用。
Token passthrough 会混淆 Client 与 Resource Server 的责任,绕过预期的令牌受众边界并增加日志泄露面,但转发本身不会修改 token 中的 aud。这会形成 confused deputy(混淆代理)风险:一个有下游权限的服务被诱导替其他调用者执行未获授权的操作。
15.3 工具与内容的两类攻击¶
15.3.1 SSRF 与网络出口¶
URL、回调地址、文件 URI 和 A2A/MCP endpoint 都是潜在 SSRF 输入。执行网络工具前应:
- 只允许
https等明确 scheme,并用 allowlist 限制域名、端口、路径与重定向次数; - 面向公网抓取的工具默认拒绝 loopback、link-local、私网、metadata IP 和 IPv6 等价地址;内部工具通过独立策略精确放行。DNS 校验须与实际连接目标绑定,每次重定向重新检查;
- 使用隔离的 egress proxy、短超时、响应大小上限和无凭据网络段;
- 对本地 Streamable HTTP MCP Server 校验
Origin,默认仅绑定 loopback,以防 DNS rebinding。
不要只按 URL 字符串过滤:域名重绑定、十进制/IPv6 地址、重定向和代理都会绕过简单黑名单。
15.3.2 Tool poisoning 与间接提示注入¶
Tool 的名称、description、Agent Card、Resource 内容和工具返回值都是不可信输入。恶意内容可能诱导模型泄露数据、扩大 scope 或调用不相关的写工具。
防御要点:
- 将工具元数据与返回内容标为不可信数据,禁止其修改系统策略、审批结果或身份;
- 安装前固定 Server 来源、版本和发布者;审阅所请求的文件、网络、环境变量和 OAuth scope;
- 以 allowlist 向模型暴露工具;高风险工具拆成只读、草稿和提交三步;
- 服务端重新校验参数、租户、对象归属与授权,不能相信模型生成的 JSON;
- 限制 Resource URI、工具输出长度和可执行内容,防止上下文投毒与数据外带。
工具 annotations(如 readOnlyHint、destructiveHint、idempotentHint)是不可信提示,不是沙箱、授权或幂等实现。描述/Schema 更新后应重新审阅;MCP 2026-07-28 的 Schema 可包含 $ref 和组合结构,解析时还要限制远程解析、递归、资源消耗与缓存作用域,避免把验证器变成新的网络入口。
15.4 最小权限、审批与审计¶
安全不是每次都弹确认框。确认应与风险绑定,且必须向用户显示将对哪个对象执行什么动作、使用什么身份、影响范围是什么。
| 风险 | 建议控制 |
|---|---|
| 读取公开资料 | 限域、速率限制、审计 |
| 读取用户/租户数据 | 用户授权、对象级访问控制、脱敏 |
| 写草稿或创建可撤销对象 | 显示预览;按策略可自动化 |
| 发布、删除、转账、改权限、外发数据 | 明确人工审批、幂等键、二次校验;能回滚的设计回滚,不能回滚的先说明后果并准备补偿 |
审计记录至少包含:请求关联 ID、用户/服务身份、Agent/Server 身份与版本、授权主体和 scope、工具名、已验证参数摘要、审批决定、结果、时间、错误及数据分类。日志应避免记录 bearer token、原始机密或不必要的个人数据。
审批还要绑定规范化后的具体参数、目标对象、执行身份和有效期。审批后若金额、收件人或工具定义改变,就重新校验并按策略重新审批,避免用户同意的是一次操作,实际执行的却是另一次。
15.4.1 A2A 的额外注意点¶
Agent Card 是能力声明,不是信任证明。按 A2A 1.0 的 securitySchemes 与 securityRequirements 完成所需认证,能力条目也可声明自己的要求。Webhook 应按约定验证 bearer token、签名或其他认证,并处理重放、重复通知与任务关联;并非所有 A2A webhook 都强制使用同一种签名方案。
任务、artifact 和 file URI 也需要对象级授权与内容扫描;“Agent 自己说已经完成”不能替代对结果、来源和写入动作的验证。
15.5 上线检查表¶
- [ ] MCP/A2A endpoint、redirect URI、issuer 和 audience 均为 allowlist;
- [ ] 公共 OAuth Client 使用 Authorization Code + PKCE S256;
- [ ] 每个资源服务器按令牌类型验证有效性、issuer、目标资源、有效期、scope 和租户;
- [ ] 未将 access token 转发给未声明的下游;
- [ ] Tool、Card、Resource 与返回值均按不可信输入处理;
- [ ] URL 工具具备 DNS、重定向、私网和 metadata 防护;
- [ ] 高影响动作有预览、明确审批、幂等性和服务端复核;
- [ ] 审计日志可关联一次任务全链路,且已做机密与隐私最小化。
15.6 常见错误¶
15.6.1 把 Agent Card 或 Tool description 当成授权证明¶
它们只是对端声明,也是潜在不可信输入。权限必须由认证身份、服务端策略和对象级检查决定。
15.6.2 只验证 token 签名,不验证 audience¶
签名有效不代表令牌是发给当前资源服务器的。还要检查 issuer、aud、到期时间、scope 与租户。
15.6.3 混淆正常携带令牌与 token passthrough¶
Client 向令牌指定的 MCP Server 携带令牌是正常流程;MCP Server 不能拿这份令牌访问其他 audience,或接受发给其他 API 的令牌来冒充自身授权。
15.6.4 用确认弹窗替代最小权限¶
用户无法审查隐藏参数和复杂调用链。审批只处理剩余高风险,基础边界仍靠 allowlist、隔离和服务端校验。
15.7 本章总结¶
- 协议互操作不建立信任,Host 与 Server 分别执行授权;
- OAuth 流程要落实 PKCE、精确回调、audience、最小 scope、轮换与撤销;
- 工具元数据、Card、Resource 和返回值都是不可信输入;
- URL、回调和远端 endpoint 必须经过 SSRF 与网络出口控制;
- 高影响动作需要明确审批、幂等、服务端复核与最小化审计。
参考资料¶
本章的参考资料、阅读建议与来源说明见集中参考资料章节。