#AI Agent#MCP#DevOps

MCP Elicitation 敏感数据边界:表单、URL 导航与完成证明

URL mode 的 accept 只表示用户同意导航,不代表授权或付款已经完成。本文隔离表单数据与敏感凭据,绑定用户身份、目标域、完成通知和原请求重试。

本文要点

  • 主题聚焦:AI Agent、MCP、DevOps
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年3月30日·更新于 2026年7月20日

Server 需要第三方 API key,于是在 form mode 里放了一个 password 字段;另一个实现改用 URL mode,却在用户点击“打开”后马上把原工具调用标为成功。更危险的是,攻击者把自己的 elicitation 链接发给受害者完成 OAuth,Server 最后把受害者 token 绑定给攻击者。交互看起来都走完了,身份与完成语义却完全错位。

MCP 2025-11-25 把 Elicitation 分为 form 与 URL 两种模式。MCP 认证边界处理 Client 访问 Server 的身份,SSO 与 OAuth解释常规授权;URL Elicitation 用于 Server 代表用户连接第三方服务,两套 token 和主体不能混为一谈。

先按数据敏感度选择通道

Client 必须在初始化声明 elicitation.form、elicitation.url 中至少一种能力;空对象仅为兼容而等价于 form。Server 不得发送未协商模式。form 的 requestedSchema 只支持扁平 object 与受限 primitive/enum,不适合嵌套业务对象。密码、API key、access token、支付凭据等授权秘密绝不能走 form;Client 在渲染前做 schema allowlist 与敏感字段分类,Server 收到后再次校验。普通联系信息虽未被协议一概禁止,也要给用户查看、修改、decline 和 cancel 的机会。

URL mode 保存 elicitationNavigation.v1:elicitationId、Server 与已验证用户 subject、原请求摘要、目标 scheme/完整 host、允许的 redirect policy、用途、创建/过期时间、状态 nonce 摘要和 session generation。URL 不能含凭据、个人信息或预认证 bearer;生产只允许 HTTPS。Client 不预取 URL 或 metadata,不自动打开,必须先展示完整 URL并突出域名,识别 Punycode 等可疑地址。打开方式要让 MCP Client 与 LLM 无法读取页面和用户输入,Web CORS/CSP 安全不能替代这个隔离边界。

text
CREATED -> USER_REVIEW -> DECLINED | CANCELLED | NAVIGATION_ACCEPTED
NAVIGATION_ACCEPTED -> OUT_OF_BAND_PENDING
OUT_OF_BAND_PENDING -> COMPLETION_NOTIFIED -> REQUIREMENT_VERIFIED
OUT_OF_BAND_PENDING -> EXPIRED | USER_RETRY
REQUIREMENT_VERIFIED -> NESTED_SERVER_CONTINUES -> ORIGINAL_RESPONSE_ACCEPTED
REQUIREMENT_VERIFIED -> ERROR_RETRY_ELIGIBLE -> OPTIONAL_CLIENT_RETRY -> RETRY_RESPONSE_ACCEPTED

Elicitation 响应有 accept、decline、cancel 三态。form 的 accept 携带已校验 content;URL 的 accept 不带 content,只证明用户同意导航,不证明 OAuth、付款或凭据录入完成。notifications/elicitation/complete 也是可选提示,Client 必须忽略未知或已完成 ID,并保留手动重试与取消入口。Server 应把外部状态绑定到经授权获得的真实用户 subject,不能只绑定 MCP session ID或 Client 自报邮箱;打开链接的人也必须与发起者为同一主体。

URL mode 有两条不同因果链。若 Server 在仍处理原请求时嵌套发送 elicitation/create,Client 回应导航决定后只能等待;Server 在外部条件验证完成后继续同一个在途请求,Client 不得自行重试。若原请求已用 URLElicitationRequiredError(-32042)结束,Client 才可把 requirement 标成 retry eligible,并 MAY 用同一原请求摘要和新的 retry generation 发起一次可选重试。两条链不能互换,否则嵌套请求仍运行时会产生第二次效果。

原业务的唯一接受点是 acceptOriginalOperation,而不是 accept 或 complete notification。它要么匹配嵌套请求原 JSON-RPC 身份、requirement receipt 和最终 response,要么匹配 -32042 error receipt、原请求摘要、retry generation 与重试 response,再原子写唯一业务 receipt。Server 对 OAuth 场景还需在回调校验 state/PKCE、redirect URI、用户绑定和 token audience,把第三方凭据只存 Server 侧秘密库;其他付款或录入流程保存等价完成证据。Client bearer 不得传给第三方,第三方 token 也不得返回 Client。短期能力租约可限制重试资格,人工审批队列承接高风险确认。

故障注入覆盖 form 请求 password、URL 含 token、相似 Unicode 域、跨域重定向、Client 预取触发一次性 nonce、攻击者转发链接、subject 不匹配、accept 后永不完成、complete 重复或先到、嵌套流被 Client 重试、-32042 流重复重试、旧 session 通知、OAuth state/PKCE 错误和凭据误入日志。断言敏感字段 form 放行数为 0,未知完成通知推进数为 0,跨用户绑定为 0,两条 lineage 的原业务合计最多接受一次。

发布门要求恶意 URL 语料拦截率 100%、合法域误拒低于 0.1%、所有 URL 导航 100% 有显式同意收据、所有第三方 token 仅存在秘密存储、完成对账 p99 低于 2 分钟、过期流程 100% 可人工恢复。上线先启用 form schema 审计,再对单一内部 HTTPS 域开放 URL mode。回滚时停止签发新 elicitation、吊销未完成 nonce 并保留查询页和对账账本;不能因关闭通知监听就把外部进行中的授权当作失败或成功。

Related

相关推荐