本文基于 Ars Technica 2026-10-05 的报道(作者 Dan Goodin)写成,技术细节与引语均转述自该文及其采访对象。Ars 原文引用的漏洞细节来自独立研究员 Syed Anas Mohiuddin 的概念验证(proof of concept,PoC)披露,我未做独立验证;部分机构名与评分以报道口径为准。
过去五个月里,Google 和另外四家机构各自承认了一类漏洞。它们的共同点有点奇怪:除了都在用 AI agent,彼此之间几乎没有交集:有做数据库的、有做网络安全的、有政府机构。研究者测试的对象更杂,包括 Google、摩根大通(JPMorgan Chase)、Weviate、Rapid7、法国政府的跨部门数字管理局,以及美国联邦政府。
同一个人,在同样一套打法下,撞出了一遍又一遍。
独立安全研究员 Syed Anas Mohiuddin 把这类攻击起名叫 protocol pivoting(协议枢转)。按他的定义,这是一个多步攻击:先通过一个协议拿到初始访问,利用协议之间的信任假设打通中间环节,最后升级到只有另一个协议才能触及的能力。
Ars 给出的标题更直接。MCP(Model Context Protocol,模型上下文协议)可能是你听说过、但不知道有多危险的协议。

攻击链:从翻译 agent 到 SSRF
机制并不复杂,值得说清楚的是它依赖的东西。
想象一个企业内部有三个角色:一个翻译 agent、一个数据分析 agent、一个存放凭据的数据库服务。它们之间通过 MCP 通信。MCP 是当前 AI 应用和 agent 之间对接的主要标准之一。
攻击者做的事只有第一步:在翻译 agent 能读到的某个内容里埋一段文字。
接下来的一切都是系统「正常工作」的结果:
翻译 agent 读到这段文字。它不会执行,它只是把它当作某个待办任务的上下文,转发给数据分析 agent:「翻译完了,顺便帮我看看这份数据」。
数据分析 agent 信任翻译 agent。在它的设计里,翻译 agent 递过来的东西就是合法任务的一部分。于是它照做了。
问题在于:MCP server(提供工具的服务端)为每个 agent 存着凭据,而 agent 之间又被设计成互相信任。所以,一个本来会被大模型本身拒绝的指令,在这条链子上畅通无阻。研究者攻击的目标根本不是大模型,而是某个具体 agent。

McKee 说得更狠:很多专用 agent(翻译、数据分析这类)根本没有像样的护栏,有的压根没有,指令就这么一路传下去了。
走廊比喻:每个人都检查自己的前门
Rapid7 漏洞情报总监 Douglas McKee 用了一个比喻:
每一个协议都假设自己独立存在,所以每一个都只检查自己的前门,却没人看中间的走廊。
攻击者要做的,就是站在走廊里,等有人从自己门前经过时递东西过去。链上每一个环节都完美履行了设计职责,正因如此才难被发现。
McKee 后面还有一句更直接的:
从 LLM 传给工具的任何东西,都应该当作来自互联网上陌生人的输入来对待——因为在 prompt injection(提示词注入)的场景里,它就是。
同一个漏洞,2.7 分和 8 分
研究者披露了两个案例,放在一起看才有意思。问题的分歧不在漏洞存不存在,而在修没修到位。
Rapid7 那个漏洞编号 CVE-2026-97228,严重性评分 2.7/10,上个月已修。同样的攻击模式,评分只有 2.7,这个分数低到会让人以为它不构成什么威胁。
Google 那个编号 CVE-2026-14540,评分 8/10。问题出在它的数据库 MCP 工具箱 googleapis/mcp-toolbox:初始化 HTTP 客户端时没有配置 CheckRedirect 策略(一组控制服务器如何处理 URL 报错或重定向的设置),同时也没有校验目标 IP 地址。
后果是 SSRF(服务端请求伪造,server-side request forgery,一种让 web 服务器代为发起未授权网络请求的漏洞):
一个精心构造的路径参数,能让这个工具箱跟随重定向指向内部端点,并以攻击者的身份发出请求。
Google 的修法值得单独说:PR #3448 在连接时检查解析出的地址(这样 DNS rebinding 也没法在校验和使用之间换目标)、加了 IP 允许与阻止列表,而且在服务启动时就拒绝不安全的 base URL,而不是等到第一次请求时。研究者自己的评价是:
这才是真正的 SSRF 防护长什么样。也比大多数 MCP server 做得多。
对比之下,同一个攻击面,一个 2.7 分,一个 8 分。这中间的差别不是漏洞有多凶,是有没有人在启动阶段就把门锁好。

摩根大通那个洞:两边单独都没有
我在这份披露里读到的最有教育意义的案例不是 Google,是摩根大通(JPMorgan Chase)。
他们的开源仓库 jpmorgan-payments/ai 里有一个文档检索用的 MCP server,带两个取内容的工具。其中 read_documentation 在抓取前会先过一遍域名允许列表。它的兄弟函数 related() 没有——它直接接受调用方给的 URL,抓取时不加任何限制。
研究员说,这是他学得最多的一例,因为没有人做错了什么明显的事。
这个组件是从一个 AWS 项目 fork 出来的。他把两个版本并排 diff 了一遍:AWS 原版根本不解析调用方的 URL;摩根的改写给它加上了抓取能力,然后把允许列表忘了。两个称职的团队,一次再普通不过的 fork 步骤,产出了一个两边代码库单独看都不存在的洞。
没有哪个扫描器会标记出这种东西。你得把两个版本并排读。
这句话值得单独拿出来说。MCP server 生态里大量组件是从别处 fork 来的,fork 时的新增逻辑恰恰是最容易漏掉安全检查的地方,而代码审查的习惯是看「新增了什么功能」,不是「新增的功能绕过了原有约束」。
扫描器为什么看不见这层
同一位研究员还解释了另一个问题:为什么 SCA(软件成分分析,software composition analysis)和各类依赖扫描工具看不见这类漏洞。
它们的工作方式是查找已知的脆弱依赖包,然后沿着代码调用图往下追。但在 MCP server 里,危险输入不走代码路径——它从传输层进来,形态是模型自己选定的工具参数,由一份扫描器从不读取的 tool manifest(工具清单)描述。调用图在传输边界就断了。
Google 那个重定向策略、摩根 fork 里漏掉的允许列表、美国联邦服务器把完整上游响应写进日志——这些都在依赖扫描器会顺利通过的代码里。没有一个依赖是有漏洞的,漏洞在于 server 如何对待它本不该信任的输入。
他自己为此写了一个开源扫描器 mcp-safeguard,通过工具接口测试 MCP server 而不需要源码,检查六类问题:SSRF、过度权限、prompt injection 面、信息泄露、认证缺口、生命周期绕过。但他在文中的自我评价很诚实:这是一个起点,不是解法,上面的发现里有好几个是必须人读源码、并排 diff fork 才发现的,模式匹配类工具(包括他自己的)会漏掉这一类里很大一部分。
他给出的结论很克制:这一层需要被检查,而目前大部分时候它没有被检查。
命名之争:这算新的攻击类吗
有意思的是学界并不买账。
同样做 AI 攻击研究的 X41 D-Sec 研究员 Markus Vervie 认为,更准确的术语仍然是 prompt injection,protocol pivoting 只是它的一个子类,准确说是「间接 prompt injection(间接提示词注入)」。他的理由是:恶意提示词来自哪个协议、在哪个协议上显形,对这类攻击能否成立并不是必要条件。
他补了一句:「当然,这种攻击是出人意料的,而且普遍很难缓解。」
McKee 则站在命名这边,他的理由更实际:给攻击类别起个名字,防守方和标准机构才会真的去为它设计防线。「给这个攻击类别命名这件事得归功于研究者,因为有了名字,防守方和标准机构才会真的去设计防线。」
两边都有道理。但从工程视角看,我倾向 McKee 的判断:一个有名字的子类,比一个埋在「间接注入」这个大抽屉里的机制,更容易在排期里排上号。
被放弃的零信任原则
Ars 提到的这层比漏洞本身更值得留意。
研究者指出,零信任(zero trust)——那个「假定网络里至少有一个节点已被感染,任何敏感操作前都必须重新授权」的核心安全原则,在企业急着搭 agent 架构的过程中被放弃了。
原因不难理解。MCP 是个新协议,而它在被充分测试和加固之前,就已经无处不在了。企业都在抢着把 agent 互联起来,互联的前提又恰恰是「agent 之间互相信任」,这两件事天然冲突。
底层的技术缺陷倒是老熟人:injection 和 SSRF,都是二十年前的坑,修复思路也没变。变的是它们现在站在的位置:从一个模型内部,挪到了协议之间没人看守的那段走廊上。
还没解决的那部分
披露里有一部分需要单独说明,因为它们的状态和上面那些不一样。
研究者向美国联邦政府 GSA(General Services Administration,联邦总务管理局)技术转型服务下的五个 MCP server 提交了私密报告:退伍军人事务部的福利申领服务、CMS 的 Blue Button、regulations.gov、USASpending、CDC 的 PLACES 数据集。全部是 2026 年 9 月 2 日提交的,至今仍在 triage(评估处理)阶段,他明确表示不把这些当作已确认的结果。
其中一个最值得警惕,他只用漏洞类别的抽象层级描述:VA 那个在调用上游福利 API 遇到错误时,会把完整的上游响应体以 ERROR 级别写进日志,不做脱敏。那些响应体里可能带着退伍军人的姓名、社会安全号、出生日期和地址。而触发它的不需要什么攻击,日常的验证失败就足够。
日本数字厅的 digital-go-jp/jgrants-mcp-server 也类似:9 月 1 日报告给 JPCERT 说该 server 没有任何认证,9 月 7 日开了公开 PR 要求绑定非 loopback 地址必须显式 opt-in,该 PR 至今未合并。
这些细节我保留在文章里,是因为它们说明了一件事:这个领域的公开战果全是已修好的,而未修好的那部分连细节都还不能公开。
如果你今天就要动手
不写空泛的「加强安全」,列几条能直接落地的:
**跨 agent 传递的内容要做来源标记。**下游 agent 拿到的不该只是一段文本,而应该带清楚「这是用户说的、还是上一个 agent 猜的、还是外部数据里读到的」。三者的信任级别天差地别。
**agent 之间的调用默认拒绝,按需授权。**这就是零信任的老办法,放在 agent 互联上同样成立。默认全信任是最省事的选择,也是最危险的选择。
**MCP server 启动时校验配置,而不是第一次请求时。**Google 的修法可以直接抄:base URL 不安全就在启动阶段拒绝,别拖到运行时。
**凭据不要集中存放在被信任链直接触达的地方。**MCP server 给每个 agent 存凭据的设计,在互信模型下等于把所有钥匙挂在了同一条链上。
研究者在文末给了一份更简短的修复清单,和上面的判断能对上:连接时(而不是连接前)验证解析出的 IP、关闭自动重定向或逐跳校验、对每一个会发起抓取的工具都套同一份允许列表而不是只写第一个、记录日志前先脱敏上游响应体。他说 Google 对 CVE-2026-14540 的修法可以当参考实现。
**给这类攻击起个名字,写进你的日志和告警规则。**McKee 的判断成立:没名字的攻击类别,监控看不见。
写在最后
这批新闻里最让我在意的不是 CVSS 8 分,是五家机构在五个月里各自撞上同一堵墙。
这说明问题不在某家实现写得烂,不在某个版本的 bug,也不在这套攻击有多高明。它非常朴素:一个翻译 agent 读了段脏文本,转手交给一个信任它的同事,同事照做了。
链上每一步都是设计好的行为,合规、合理、无辜。安全性恰恰不来自「每一步都做对」,而来自「某一步做错时不至于连坐」。这段路我们走了一百年才学会的东西,agent 互联正在从头学一遍。
McKee 那句「谁来看走廊」,会是我一段时间内反复想起的话。
参考来源
- MCP for agent-to-agent comms may be the riskiest protocol you’ve never heard of(Ars Technica,2026-10-05,已入库 9.4KB)
- Protocol Pivoting(Mohiuddin 的研究披露页)
- Rapid7 CVE-2026-97228 漏洞记录
- Protocol Pivoting, Four Months Later(研究者更新披露,2026-10,本文第二、三节数据来源)
- Protocol Pivoting 正式论文(Zenodo DOI 10.5281/zenodo.20371152)
- mcp-safeguard(研究者自建的开源扫描器)
- Model Context Protocol 官方文档
- From prompt injections to protocol exploits: Threats in LLM-based applications(ScienceDirect)
可信度边界:本文内容转述自 Ars Technica 报道及其采访对象(Syed Anas Mohiuddin、Douglas McKee、Markus Vervie),并补充了研究者 2026 年 10 月的个人更新披露,漏洞细节与 CVSS 评分来自其 PoC 披露,未经我独立复现;机构名单与评分为披露当日口径,后续可能修订。「五家机构承认漏洞」与「研究者测试的机构名单」在原文中是两组不同表述,本文已分别标注,未合并计算。文中关于美国联邦政府五个 server 与日本数字厅的案例,研究者本人明确标注为「已报告、仍在 triage、未确认修复」,本文保留了同样的保留措辞,未当作既成事实。防御清单中的前五条为基于报道信息与零信任原则的推论,后一段为研究者本人给出的修复建议。