ChatGPT 静默地在连接器间传递数据,悬赏要求一张身份证。
ChatGPT silently passes data between connectors and the bounty wants an ID card

原始链接: https://community.openai.com/t/security-follow-up-tool-call-silently-routed-to-a-different-connector/1413053

在一次 ChatGPT 对话中,两个连接器指向同一个 MCP 服务器但使用不同的 OAuth 客户端,模型通过连接器 A 启动了一个确认流程。用户在 A 的小组件中确认,产生了一个一次性代码。随后的调用却静默地使用了连接器 B,并携带了 A 的代码,因该代码绑定到 A 的 OAuth 客户端而被拒绝。这种静默的连接器切换可以在没有用户同意的情况下在不同的应用/OAuth 授权之间传递数据。共享的 MCP URL 并不意味着连接器等价;连接器及其 OAuth 客户端才是信任边界。预期行为:后续的工具调用必须使用启动该流程的同一个连接器和 OAuth 客户端。

Hacker News 上一个帖子讨论了 ChatGPT 在连接器之间静默传递数据,以及 OpenAI 的漏洞赏金要求身份验证。该赏金的身份验证要求源于 Bugcrowd 要求所有研究人员进行身份验证,以减少 AI 生成的垃圾提交,尽管有些人猜测这与制裁合规有关。评论者讨论了权衡:身份检查减少了垃圾信息,但可能让匿名安全研究人员却步;有人建议使用 PGP 或手写明信片等古怪过滤器。人们担心身份提供商 Persona 背后有 Peter Thiel 的 Founders Fund 支持。其他人指出匿名研究人员可以通过加密货币获得报酬,而因报告流程繁琐,沮丧的研究人员可能会公开披露漏洞。一位评论者称 OpenAI 像“病毒”一样封号——该说法大多被驳回。一个技术点澄清,是主机而非 MCP 协议静默地在连接器之间路由了代码。帖子还包含关于在 Tor 上出售漏洞和拒绝保密协议的抱怨。
相关文章

原文

In a conversation with two connectors enabled, ChatGPT made a follow-up tool call through a different connector than the one that started the flow. The user was not told about the switch. The call carried a one-time confirmation code from the first connector’s widget.

Setup

- One ChatGPT account with two connectors enabled that point to the same MCP server.

- Connector A is a custom connector added in developer mode.

- Connector B is the published app from the app directory.

- Each connector has its own OAuth client, so the server sees two separate clients for the same user.

Steps

1. In a conversation with both connectors enabled, ask for an action that needs the user’s confirmation.

2. The model calls a confirmation tool through connector A. Its MCP Apps widget shows the change. The user confirms, and the widget sends a one-time confirmation code to the conversation via ui/message.

3. The model makes the follow-up call with that code, but silently through connector B instead of connector A.

Result

The server rejects the call, because the code is bound to connector A’s OAuth client. Every attempt in that conversation failed. In the attempt we logged in detail, the code was confirmed through connector A and redeemed through connector B. Nothing told the user that the follow-up call went to another connector.

Why this is a problem?

The user starts the flow with connector A and confirms in connector A’s widget. The follow-up call then goes to connector B without the user knowing, and it carries a value produced in connector A’s widget. Connectors are separate apps with separate OAuth grants, so this silent switch passes data from one app to another without the user’s consent.

Here both connectors came from the same provider, so our server-side binding stopped the call. With a third-party connector enabled in the same conversation, we expect the same silent switch to pass one app’s data to another provider if the server URL is shared.
A shared MCP URL is not enough to treat two connectors as one. Behind the same URL, a server can act for different parties depending on the OAuth client, for example separate tenants, partners or environments. The boundary is the connector with its own OAuth client, not the URL.

Expected behavior

Tool calls are matched to a connector by its OAuth client, not by the MCP server URL. A follow-up call goes through the same connector and OAuth client that started the flow.

联系我们 contact @ memedata.com