# 开发者报告：ChatGPT 换了连接器，确认码被服务器拒绝

**Summary:** 一位开发者报告，ChatGPT 把用户在一个连接器里拿到的确认码，带进了另一个连接器的后续调用，服务器以 OAuth 客户端不匹配为由拒绝。我认为拒绝本身是对的，但助手本该守住用户选中的那条连接，让分步动作全程带着发起时的授权上下文。

- Canonical: https://markhuang.ai/zh/news/chatgpt-confirmation-connector-switch
- Language: zh-CN
- Author: [Mark Huang](https://markhuang.ai/about)
- Published: 2026-11-06
- Section: News
- Tags: ChatGPT, MCP, OAuth, 应用连接器, AI 安全, 用户同意
- Source: [OpenAI Developer Community](https://community.openai.com/t/security-follow-up-tool-call-silently-routed-to-a-different-connector/1413053)
- License: https://creativecommons.org/licenses/by-nc/4.0/

---

![一枚蓝色确认码挂在一把锁上，却对不上第二把锁；第二把锁保持关闭，亮着红色指示灯](https://cdn.markhuang.ai/news/chatgpt-confirmation-connector-switch/hero.webp)

*概念示意图：一次确认属于某一条特定的连接。在开发者的报告里，服务器拒绝让它经另一个连接器生效。*

一位开发者报告，ChatGPT 把用户在某个应用连接器里拿到的确认码，带进了另一个连接器的后续调用。服务器拒绝了这次调用。拦下来是对的。真正该问的是：确认码一开始怎么会走另一条连接。

在 [2026 年 11 月 5 日发表于 OpenAI 开发者社区的帖子](https://community.openai.com/t/security-follow-up-tool-call-silently-routed-to-a-different-connector/1413053)里，AldiPower 说同一段对话里启用了两个连接器，两者都指向同一台服务器，却各用一套独立的 OAuth 客户端。我希望一次批准能始终绑在提出请求的那条连接上。把应用接进 ChatGPT 的人，需要知道自己确认的是哪个应用，以及它用哪套权限把动作做完。

连接器让 ChatGPT 能用某个应用提供的工具。这些工具通过 MCP（Model Context Protocol）与服务器通信。OAuth 管的是授予已连接应用的权限。两件事得分开看：两条连接可以连到同一个地址，各自手里的授权却不同。

## 同一台服务器，两条互不相干的连接

按 AldiPower 的说法，连接器 A 是在开发者模式里添加的自定义连接器，连接器 B 是服务商在应用目录上架的应用。两者同属一个服务商，服务器也为同一个用户识别出两个独立的 OAuth 客户端。

用户是在 A 里发起这个动作的。A 的内嵌控件先展示将要执行的改动，请用户确认。用户同意后，控件把一次性确认码发进对话。开发者说，ChatGPT 随后拿这个码通过 B 提交，全程没告诉用户换过连接。

一次性确认码记录的是对某个应用动作的批准，和真正发起请求时用的 OAuth 凭据是两回事。服务器把这个码绑死在 A 的 OAuth 客户端上，拿到 B 去兑换自然失败。作者说那次对话里每次尝试都失败了，并详细贴出其中一次尝试的日志。

报告里的顺序是这样的：

```mermaid
flowchart TD
  A["连接器 A 请求确认"] --> B["用户在 A 的控件里确认"]
  B --> C["控件把一次性确认码发进对话"]
  C --> D["后续调用改用连接器 B"]
  D --> E["服务器发现 OAuth 客户端不同"]
  E --> F["服务器拒绝该确认码"]
```

服务器这道拒绝我会原样留着，同时去查路由是怎么走的。一旦 B 也能接受 A 的码，这次抓出问题的那道检查也就形同虚设了。

## 动作被拦下了，路由的问题还在

按帖子的说法，服务器的防护起了作用。两条连接指向同一个服务商，操作失败了。这份描述没有证明信息被透露给了无关公司，也没有出现一次已完成的越权操作。

AldiPower 还担心一件事：同一个服务器地址，可能因为 OAuth 客户端不同而服务不同的主体。这确实是该保留连接身份的理由。不过“透露给第三方”目前只是假设，光凭帖子里的设置推不出这个结果。

原因也还没查清。帖子讲的是作者从自己日志里看到的东西，既没贴底层调用记录，也没有第三方独立复现。本文查阅的三个帖子都没有 OpenAI 员工的回复。从这串讨论里，没法知道 ChatGPT 为什么选了 B，这个行为有多普遍，OpenAI 有没有确认这是缺陷。

用户在 A 里批准了一项改动，自然期待由 A 把它做完。服务器拦是拦住了，可它解释不了助手为什么改用 B。拒绝错误授权是服务器该做的事；把动作留在用户选中的那条连接上，是助手该做的事。

## 批准要落到具体的连接上

[Simon Willison 在 2025 年 4 月分析过 MCP 的安全问题](https://simonwillison.net/2025/Apr/9/mcp-prompt-injection/)：私密数据一旦碰上能把数据送出去的工具，就是危险组合；他主张把工具调用做成用户看得懂的样子。这套分析有助于理解为什么一次调用的去向很要紧，但它不能证明这次事件就是提示注入造成的。

OpenAI 的[认证文档](https://developers.openai.com/plugins/build/auth#implementing-token-verification)把令牌校验和针对具体服务器的策略检查，放在接收请求的服务器这一侧；[安全指南](https://developers.openai.com/apps-sdk/guides/security-privacy/)也要求明确的用户同意，以及服务器端对输入做校验。就算助手已经把确认控件展示给用户，这些责任也照样得由服务器承担。

这种要分好几步才能做完的操作，我的偏好很简单：从发起的那条连接开始，把它的授权上下文一路带到动作结束。如果助手确实要用另一条连接，就得说明换成了哪条，再为这条连接单独征得同意。用户批准的不只是要做什么，也包括由谁去执行。

如果你手上的自定义连接器和上架应用指向同一个服务，这份报告提示了一个很具体的检查：从一条连接发起确认，再验证另一条连接兑不掉它。多记一点连接信息，出问题时好定位不匹配，但确认码本身别写进日志。这个检查我自己还没跑过。

我在[分析 Postman 安装器](/news/postman-installer-self-approves-ai-hook)时写过类似的判断：系统的权限应该对应用户真正做过的选择。这一次按报告说，服务器把这条区分守住了。轮到助手挑连接的时候，我希望它也一样。
