两分钟内发了九条

2026 年 10 月 27 日,协调世界时 13 点 07 分到 13 点 08 分之间,VulnCheck 以 CNA 身份发布了九条 CVE 记录。九款互不相关的 MCP 工具服务器,不同维护者、不同语言、解决不同问题——其中八款犯的是同一个错。

具体名单是:ai-sdlc(CVE-2026-117558)、DroidMind(CVE-2026-117559)、ATXP 的 Gemini CLI 扩展(CVE-2026-117560)、sf-mcp(CVE-2026-117561)、esp-mcp(CVE-2026-117567)、mcp-ffmpeg(CVE-2026-117568)、Kali-GPT(CVE-2026-117569)、nmap-mcp(CVE-2026-117570)与 hagent(CVE-2026-117573)。八条是 CWE-78 操作系统命令注入,剩下一类是过于宽松的允许列表。七条的评分是 CVSS 3.1 得 7.8 分、CVSS 4.0 得 8.5 分。

把它们放在一分钟里发出来,本身就是一种表达:这不是九个孤立的疏忽,而是一种写作习惯。

九款互不相关的 MCP 服务器,八款犯的是同一个错2026 年 10 月 27 日 13:07 至 13:08(UTC),VulnCheck 作为 CNA 发布同一个模式:工具参数直接拼进 shell 命令字符串execSync / child_process.exec / subprocess.run(shell=True) / create_subprocess_shell八条 CWE-78命令注入,未中和$() 与反引号不同语言同样写法七条 7.8 分CVSS 3.1 7.8CVSS 4.0 8.5另两条分数更低八条无修复版只有 ai-sdlc 有补丁四条以 commit 定界没有版本号可升五款试过防御:三款做了允许列表,一款写了转义函数全部被 $() 或反引号绕过,且写在彼此独立的代码库里端到端攻击路径:投毒文本进入上下文,智能体把恶意字符串填进工具参数
图|九条 CVE 覆盖 ai-sdlc、DroidMind、ATXP、sf-mcp、esp-mcp、mcp-ffmpeg、Kali-GPT、nmap-mcp 与 hagent,其中八条是同一类命令注入。

最短路径就是那条错的路

缺陷的形态高度一致:某个可由智能体调用的工具参数,被直接拼进一条 shell 命令字符串,中间没有对 $() 和反引号做中和。具体入口因项目而异——Node 侧的 execSync 与 child_process.exec,Python 侧的 subprocess.run(shell=True) 与 asyncio.create_subprocess_shell,落点各不相同,写法如出一辙。

要理解为什么九个团队会走到同一个坑里,得看这个场景的激励。MCP 工具服务器大多是围绕某个命令行程序快速包一层:想让智能体能跑 nmap,最短路径就是拼一条命令字符串塞给 shell。教程这么写,示例代码这么写,于是产品也就这么写。这不是注意力不够,而是默认情况下的产物。

更值得注意的是,五款其实尝试过防御:三款做了允许列表,一款专门写了转义函数。全部被 $() 或反引号绕过,而且是在彼此独立的代码库里分别被绕过的。这一条对防守方的提醒很直接——允许列表应该被当作风险线索,而不是控制手段。

修复状态比分数更刺眼

九条里只有 ai-sdlc 有补丁,对应提交 717d7ec。它的修复方式值得抄:不再用 shell 字符串拉起 gh,改成参数数组,同时给 repo 字段加上 owner/name 结构化校验,并补了单元测试。这是教科书式的改法——它关闭的是整条注入路径,而不是去拉长一份字符黑名单。

其余八条没有修复版本,其中四条只能用提交哈希来界定影响边界,因为项目根本没有版本号可升。这对任何做资产清点的人来说都是难题:你没法写一条「升级到 X 版本以上」的规则,只能去比对提交记录。

字段记的是调用者的位置,不是投毒内容的位置计分表写的样子攻击向量:本地(AV:L)所需权限:低(PR:L)看上去像内部人员的本地风险分诊规则按此降级处理实际发生的事情攻击者在远端,从未接触机器投毒载体:邮件、短信或仓库名、磁盘上的文件名本地调用者是智能体,不是人对防守方的含义按 AV:L 或 PR:L 降级的分诊规则,会把这一整类漏洞整体丢弃正确修法参考 ai-sdlc:改用参数数组拉起子进程,加上结构化字段校验把允许列表当成线索而不是控制手段;给每个会开 shell 的服务器做沙箱目前没有公开声明提到在野利用
图|CVSS 记录的攻击向量与权限字段描述的是智能体这个本地调用者,而真实的投毒者来自远端,两者在分诊时容易被混为一谈。

评分模型把攻击者写成了智能体

这批记录里最值得讨论的不是漏洞本身,而是评分。每条注入记录都带着 AV:L(攻击向量:本地)与 PR:L(所需权限:低)。这两个字段描述的是智能体——它确实是本地的、确实持有低权限凭据。

但真正的攻击者并不在这台机器上。投毒载体可能是一封邮件、一条短信、一个仓库名,或者磁盘上的一个文件名,攻击者从头到尾没有接触过目标主机。换句话说,CVSS 记录的是调用发生的位置,而不是恶意内容进入的位置。

这个错位有实际后果。很多企业的分诊规则会对 AV:L 降权处理,把 PR:L 理解为内部人员风险。照这套规则走,这一整类漏洞会被整体丢弃——不是判为低危,而是根本不会进入处理队列。

该做的三件事,与不必恐慌的两件事

要做的:清一遍开发者机器上的 MCP 客户端配置,搜 shell=True、execSync、child_process.exec 与 create_subprocess_shell 这些没有参数数组的调用;给每个会开 shell 的 MCP 服务器配最小权限用户和沙箱;把工具参数当成和 HTTP 查询串一样的不可信输入来威胁建模。

不必恐慌的两件事也要说清楚。其一,这批记录的攻击向量定级并非全无道理,攻击者确实得先让某段文本进入智能体的阅读范围,这不是可以批量扫描互联网直接打的情况。其二,目前没有公开声明提到在野利用,也没有既成损失的报告。

本站此前记过的几轮披露可以和它连成一条线:从单款工具的越权与密钥外泄,到网关层的授权缺失,再到这九条。变化的不是漏洞类型——命令注入是几十年前就被写进教科书的毛病——变化的是谁在替攻击者按下回车。