先看清一批被读错的公告
9 月 15 日,美国漏洞库在一个两秒的窗口内发布了一款智能体构建工具 Flowise 的十条 CVE,时间落在 16:17:43 至 16:17:45 之间,涉及版本全部在 3.1.4 之前,基础评分从 7.6 到 9.0。其中两条 9.0 是远程代码执行:一条落在自定义 MCP 节点,另一条是 MCP 服务器配置的校验绕过。
三条被普遍读错的地方需要先纠正。
同一秒内出现十个编号,是一个产品的协调披露批次,而不是十起独立攻击。把它报成「某工具一天被攻破十次」,是把一次发版流程读成了一次安全事件。
这些条目的描述里多数写着「已认证的攻击者」或「已认证用户」,也就是说它们是产品内部的租户隔离与权限边界失效,不是面向互联网的免认证利用。
没有任何一条被报告已在野利用。它们是已修复的漏洞,并且给出了修复版本。
分母:1.4% 这个数字为什么重要
同一份统计口径下,把窗口放宽到访问漏洞库前的 22 小时,截至 9 月 16 日 11 时,总计 1471 条 CVE。其中文本提到 MCP 的有 21 条,包含完整短语「Model Context Protocol」的有 17 条。占比约 1.4%。
这个分母不能证明生态是安全的,但它确实否掉了一个流行说法。当「MCP 千疮百孔」被反复引用时,没有人给出比例;一旦给出分母,断言就需要重新表述。
真正有信息量的是分布而不是比例本身。在同一天里,出现问题的对象包括一个工具运行沙箱、一个搜索代理、一个密钥保管服务、一个代码托管平台的 MCP 服务器、一个广告平台的 MCP、两个 MCP 网关、一个记忆服务器、一个内容管理系统服务器与一个数据库服务器。也就是说,MCP 工具层——网关、注册表、记忆服务、搜索代理——正在以稳定的日频产出公告。这是一个关于智能体安全位置的、可复现的说法,比又一个提示注入演示更有说服力。
形状是重复的:集成面就是攻击面
把描述放在一起读,可以看到一条压倒性的模式:一个由调用方控制的路径、地址或配置值,最终抵达了文件系统、一次对外的网络请求,或者一个 shell。
仅 Flowise 那一组里就包含:结构化查询节点里的文件路径校验失败、对话模型节点里未被校验的基地址、数据库查询里未净化的会话标识,以及抓取节点的服务端请求伪造。这些都是集成面的缺陷,而智能体工具层几乎整个都是集成面——它的本职工作就是把外部系统的能力接进来。
还有一条更直白的例子。一个智能体栈在 1.1.0 版本之前接受明文 HTTP 的 MCP 服务器注册表后端(CVE-2026-91988,9 月 15 日更新,CVSS 4.0 评分 9.2)。中间人可以改写目录响应,注入任意的命令与参数,这些内容随后被客户端的连接池当作本地子进程生成,从而在智能体宿主机上实现代码执行。整条链路里没有模型参与,也不需要宿主机上已有管理员权限。
蜜罐里的 90 天:攻击者把网关当成了凭据仓库
另一组材料把视角从漏洞换到了攻击者。有安全团队用仿冒模型网关、MCP 服务器与多种编排框架的蜜罐,记录了持续约 90 天的定向攻击,被仿冒的对象包括开源模型代理、MCP 服务、编排框架、低代码平台与自动化工具。
其中最值得逐层看的是针对模型网关的那条链。一个鉴权绕过漏洞允许用一个字符的 bearer 令牌通过 MCP 网关鉴权;一个测试端点存在命令注入;两者再叠加框架层的请求头绕过,构成免认证的远程代码执行。外部研究把这条利用链与一个勒索软件团伙关联起来。攻击者提交了一份伪造的 MCP 服务器配置,其命令字段会拉起一个下载器与挖矿程序,而测试接口仍然返回了看起来正常的一次握手,把滥用掩盖过去。
另一个动作更能说明「网关等于凭据仓库」:攻击者直接在运行中的 Python 进程里取走代理主密钥。这类密钥可能从未以文件形式落在磁盘上,因此常规的磁盘扫描与配置审计看不到它。同一个案例里,攻击者还检查了常见配置路径并列举可用的后端模型,再挑选窃取密钥或消耗付费容量的目标。
其余手法同样成体系。盲提示注入被用来诱使持有 shell 权限的智能体执行命令,确认方式是通过带外回调;命令做 Base64 编码、载荷放在公共粘贴站,以降低日志与基础过滤器的可见度;在自动化工具上投放挖矿程序;在低代码平台上,矿工被藏进一个以点开头的目录并改名,伪装成开发环境里的普通文件。
授权决策发生在启动之前,而不是调用之时
把上面这些放在一起,可以得到一个比「打补丁」更根本的结论:真正区分「一个会执行命令的工具」与「一个会执行命令的攻击者」的决策,发生在进程被创建之前,而不是工具被调用的那一刻。
理由很直接。当一个 MCP 服务器进程已经在运行,它已经持有宿主机赋予它的权限;此时再去逐个授权工具调用,是在爆炸半径内部设卡,而不是在边界上设卡。有公开案例正好证明了这一点:某个 MCP 服务器把访问控制的环境变量写在工具列表的展示处理里,却没有写进实际调用的执行路径,于是部署方看到的是「已经限制到只读」,而调用层并不同意。展示层的过滤是装饰性的。
更上游的风险是配置即供应链。一个被投毒的依赖包、一份被塞进来的编辑器配置、一个看似帮忙的合并请求,只要它能写入 MCP 的配置,就获得了一条在下次启动时免认证执行任意命令的路径。这里同样不需要模型的参与。
因此更稳妥的落地姿态是默认拒绝式的启动审批:在宿主机启动服务器进程之前,先判断这个服务器、这个命令行、这组参数、这套环境变量与运行身份是否在允许清单内,并且要求路径是固定的绝对路径而不是拼接出来的字符串;这次启动必须绑定到具体的用户、具体的智能体与具体的用途,而不是「谁打开了编辑器谁说了算」;凡是会触及 shell、凭据或文件的服务器,都要有人工审批,和一次生产变更同等对待;在产生效果之前先写下决策记录,让启动本身可审计,而不是事后从日志里拼凑。调用方拿不出针对即将执行的那条命令的明确许可与已记录的批准,就应当拒绝。
配套的三条工程做法是:把决策与效果分离开,避免像前述案例那样在展示层与执行层之间发生漂移;能够用受治理的 HTTP 传输替代标准输入输出通道时就替代;对智能体服务器做运行时监控,重点关注派生子进程、下载归档文件与异常的外部连接。
这份材料真正改变的是什么
智能体安全过去一年的传播方式是演示驱动:一段提示注入、一次沙箱逃逸、一个被说服的智能体。演示有冲击力,但它不告诉你问题有多普遍、集中在哪一层。
九月中旬这两组材料给出了另一种可能:给漏洞一个分母,给攻击者一份行为记录。结论也随之变得不好听也不难听——漏洞数量少于标题给人的印象,但位置高度集中,且集中在最难通过换个模型来解决的那一层。对正在把智能体接进生产系统的团队,这意味着安全预算应当优先投向进程启动边界的治理与集成面的输入校验,而不是投向提示词层面的加固。
目前官方及行业暂未披露更多细节,后续将持续跟进迭代动态。