Mistral Vibe 的 Shell 权限绕过可导致任意代码执行

blog.secmate.dev 发布日期待确认

Mistral Vibe 在检查 shell 命令权限时,只依赖命令的简化表示,实际执行的却是原始字符串。这个差异让本应归为只读的命令,绕过了预期的审批提示,直接变成代码执行。

在审查 Mistral Vibe 2.25.0 时,SecMate 发现两个相关缺陷:

  1. SECMATE-2026-0038: 权限解析器漏掉的 shell 语义可以被用来执行任意代码。
  2. SECMATE-2026-0039: 重定向、扩展和选项值可以读写授权工作区之外的内容。

如果攻击者通过仓库投递内容,就需要 Vibe 处理这些内容,并且模型要发出构造好的 shell 工具调用。一旦这个工具调用到达 Bash 工具,权限绕过就开始了。

SecMate 于 2026 年 9 月 5 日向 Mistral 报告了 SECMATE-2026-0038 和 SECMATE-2026-0039。HiddenLayer 于 9 月 11 日发布公告,Mistral 于 9 月 12 日发布 Vibe 2.25.4。[1] [2]

据 Mistral 称,HiddenLayer 曾询问安全联系人,但在发布前没有分享漏洞细节。这些 CVE 在 Mistral 将其与 SecMate 独立提交的报告核对之前就已公开。Mistral 仍在与 HiddenLayer 一起审查受影响的版本和 CVSS 评分。

SecMate 的报告编号按安全边界对漏洞分组,与公开的 CVE 编号并非一一对应。

被打破的安全边界

Vibe 的 Bash 工具用 Tree-sitter 提取命令名和部分参数。它把这些提取出的字符串与允许列表比对,并检查识别出的路径是否在工作区内。如果每个提取出的命令看起来都安全,resolve_permission() 就返回 ALWAYS。随后代理循环会直接执行工具,不再询问用户。

但 shell 收到的是未经处理的原始命令字符串。于是,权限检查忽略的赋值、替换、重定向和命令专属选项,都会被 shell 实际求值。

有漏洞的提取器让这种不一致暴露无遗:[3]

for child in node.children:
    if child.type in {
        "command_name", "word", "string", "raw_string", "concatenation"
    }:
        parts.append(child.text.decode("utf-8"))

# 稍后,真正到达 shell 的是原始命令,而不是 `parts`。
proc = await spawn_shell_command(args.command, cwd=self.cwd)

图 1. 同一条命令字符串,两种解读。权限层丢掉环境变量赋值,只看到白名单里的 cat README.md,于是返回 ALWAYS,不弹审批提示。shell 则保留赋值,把 cat 解析到仓库里可控的 ./bin/cat。安全影响是任意代码执行;演示环节进一步窃取了受害者的 Mistral token。

恶意仓库内容会诱导模型发出工具调用 PATH=./bin:$PATH cat README.md。权限层丢掉环境变量赋值,只看到白名单允许的 cat README.md,返回 ALWAYS,因此不出现审批提示。shell 收到的却是原始字符串,应用赋值后把 cat 解析到仓库可控的 ./bin/cat。结果就是以 Vibe 进程身份执行任意代码;概念验证通过窃取受害者的 Mistral token 来演示这一点。

第一步涉及模型选择,取决于内容和模型行为。一旦构造好的工具调用存在,权限判定和 shell 执行就是确定的。生成的代码以 Vibe 进程身份运行。在该用户的系统权限和运行时控制允许范围内,它可以读取或修改文件、启动进程、调用本地工具、建立网络连接。数据窃取只是该进程可执行操作中的一种可能结果。

攻击者可以通过多种途径把精心构造的指令送到 Vibe 面前:通过社会工程,诱骗开发者克隆并查看恶意仓库;攻陷开发者本来就信任的仓库;或把一个恶意或被篡改的子模块引入到原本合法的项目中。提交信息、项目说明、文档、issue 以及工具输出,都可以携带这些指令。无论哪种途径,Vibe 都必须处理这些由攻击者控制的内容,并发出那个被构造出来的工具调用。

如果想了解更多编码智能体的背景,可以参考 SecMate 的生成项目安全基准以及后续对 AI 生成 C++ 的分析。

SECMATE-2026-0038:一条白名单命令就能执行任意代码

环境变量赋值原本与命令分开解析。权限检查可能把下面这段判断成正常:

mkdir -p bin
printf '#!/bin/sh\nprintf "PATH_HIJACK_EXECUTED\\n"\n' > bin/cat
chmod +x bin/cat
PATH=./bin:$PATH cat input.txt

解析器看到的是白名单中的命令 cat input.txt。但真实 shell 仍会应用攻击者控制的 PATH,于是 cat 被解析为 ./bin/cat,并打印出标记。

旧版和管理版的权限解析器都返回了 always;旧版 Bash 运行器执行了被替换的程序。这就是以 Vibe 进程权限执行的任意代码。

同一个根因不只影响 PATH。我们复现了四条执行路径:

被检查隐藏或归一化的 shell 特性 白名单表面 结果
环境变量赋值 cat 攻击者选定的可执行文件通过 PATH 运行
GIT_EXTERNAL_DIFF 赋值 git diff --ext-diff 仓库中的辅助程序被执行
拆分的 find -exec 谓词 find find 启动了任意程序
未加引号的 heredoc 中的命令替换 cat 嵌套的 shell 命令被执行

我们的公开 PoC 用的是 PATH 变体,把它塞进一条仓库验证指令里。只要 Vibe 照着执行,权限层看到的命令是 cat README.md,而 shell 实际把 cat 解析成了仓库里那个冒名顶替的脚本。演示脚本只做两件事:创建一个无害的标记文件,再把受害者的 Mistral token 偷出来。这两步就足以证明仓库里的代码真的跑起来了,而且能碰到 Vibe 的环境。

Git 变体是另一条借仓库投递代码的路径。恶意仓库可以把指令藏在 Vibe 会读取的内容里。只要模型发出那条精心构造的 git diff 调用,Git 就会启动仓库自带的 external diff 外部程序。这个子进程会继承 Vibe 的环境变量,其中包括通过环境变量传入的 MISTRAL_API_KEY。

GIT_EXTERNAL_DIFF=./steal.py git diff --ext-diff

权限界面里只显示了 git diff --ext-diff。而 Git 和 shell 都把前面的变量赋值保留了下来,正是这个赋值指定了 ./steal.py。

我们的受控演示完整走了一遍 PATH 链路:从攻击者控制的仓库内容,到在受害者机器上执行代码,再到窃取受害者的 Mistral token。

SECMATE-2026-0039:工作区检查漏掉了 shell 表达文件路径的各种方式

Vibe 本来还会在 shell 命令访问当前工作区之外的路径时弹出审批请求。但这个检查只看被选中的位置参数(positional token)。以 - 开头的参数不看,变量不展开,重定向目标也不检查。

在我们的 2.25.0 PoC 中,下面这些命令全都被判定为 always:

cat $POC_OUTSIDE/secret.txt                   # 变量展开后读取
cat < /tmp/outside/secret.txt                 # 重定向读取
echo overwritten > /tmp/outside/target.txt    # 重定向写入
sort -o/tmp/outside/sorted.txt input.txt      # 路径藏在选项里
git log -1 --output=/tmp/outside/log.txt      # 路径藏在 Git 选项里

PoC 用的是临时同级目录里构造出来的文件。最终确认:以 Vibe 进程的操作系统权限,可以读取和写入工作区之外的文件。

单独来看,SECMATE-2026-0039 让攻击者能够访问原本受工作区审批边界保护的文件。再结合 SECMATE-2026-0038,恶意流程就能找到凭据、执行代码,并在用户毫无察觉的情况下外传数据,完全绕过用户依赖的审批提示。

影响:任意代码执行与数据外泄

开发者代理运行的地方,正是高价值数据的所在地。以 Vibe 进程身份执行代码,意味着该身份及其所在操作系统或容器沙箱允许的任何操作都可以进行:读取、修改或删除源文件;启动进程;调用编译器和包管理器;篡改构建产物;访问本地服务;以及建立网络连接。

在没有额外沙箱的典型 Linux 安装环境中,这种访问权限可能覆盖 SSH 密钥、云服务凭据、包注册表令牌、模型 API 密钥、配置文件,以及该用户可读的专有源代码。在 macOS 上,Keychain 访问控制和施加于 Vibe 的任何沙箱可以保护部分凭据和文件。具体暴露范围取决于进程权限、授权(entitlements)以及凭据存储方式。我们的概念验证(PoC)在 Linux 和 macOS 上演示了完整攻击链:模拟社会工程学攻击诱导受害者与恶意仓库交互;当 Vibe 发出精心构造的工具调用时,仓库控制的代码便在受害者机器上执行,随后外传受害者的 Mistral 令牌。攻击者也可以改为外传该进程可访问的任何数据,或将这一代码执行原语用于其他目的。

受控概念验证海报

受控概念验证。 该视频由 AI 基于受控的 PoC 仓库 生成。它模拟了社会工程学攻击诱导受害者与恶意仓库交互的过程。在 Linux 和 macOS 上,如果 Vibe 发出精心构造的工具调用,仓库控制的代码就会在受害者机器上执行,随后外传受害者的 Mistral 令牌。

CVE 重叠情况与受影响版本

SecMate 报告的编号对应两个安全边界。公开 CVE 把 shell 行为划分成更细的类别,两者范围存在重叠,并非一一对应。Mistral 告诉我们,把拆分的 find -exec 和 heredoc 演示单独归到 CVE-2026-87986,可能与 CVE-2026-87985 重叠。因此我们把这两项演示列在报告 SECMATE-2026-0038 下,不强行归到某一个 CVE。

SecMate 报告 SecMate 演示的行为 与公开 CVE 的关系
SECMATE-2026-0038 环境变量赋值,包括 PATH 和 GIT_EXTERNAL_DIFF CVE-2026-87987
SECMATE-2026-0038 未加引号的 heredoc 中拆分的 find -exec 与命令替换 CVE-2026-87985 和 CVE-2026-87986;范围可能重叠
SECMATE-2026-0039 未检查重定向目标 CVE-2026-87984
SECMATE-2026-0039 变量展开的路径 未主张专属 CVE 映射
SECMATE-2026-0039 藏在有副作用的选项里的路径,包括 sort -o 和 git --output CVE-2026-87988

Mistral 的安全公告给出了以下公开分类和受影响版本。这些描述并不重新界定 SecMate 报告 SECMATE-2026-0038 和 SECMATE-2026-0039 的范围。1

公开 CVE Mistral 分类 受影响版本 原始报告变体的修复版本
CVE-2026-87984 Shell 重定向目标 1.3.4 至 2.25.3 2.25.4
CVE-2026-87985 ANSI-C 引用参数 2.9.0 至 2.25.3 2.25.4
CVE-2026-87986 命令解析不完整 1.3.4 至 2.25.3 2.25.4
CVE-2026-87987 环境变量赋值 2.6.0 至 2.25.3 2.25.4
CVE-2026-87988 命令允许列表与路径校验缺失 2.15.0 引入;2.20.0 和 2.23.0 部分修复;报告中的选项绕过直到 2.25.3 仍存在 其余报告变体在 2.25.4 修复

上面列出的 2.25.4 条目,指的是 SecMate 报告覆盖的特定原始变体以及与之重叠的公开 CVE。这些条目并不涵盖后来发现的权限绕过路径。

请升级到 Mistral Vibe 2.25.8 或更高版本,重启正在运行的会话,并用 vibe --version 确认版本。8

Mistral 在审阅本文时确认,2.25.4 修复了 SecMate 最初概念验证(PoC)涉及的路径;2.25.5、2.25.7 和 2.25.8 则进一步加固了权限绕过问题,其中包括 less / LESSOPEN / --lesskey-src 这条路径。6 7 8

2.25.4 改了什么

2.25.4 补丁去掉了一个假设:解析不完整就是安全的。[4]

最关键的设计变化是失败即拒绝(fail closed):权限层无法建模的语法,不再有资格自动执行。

要点

负责任披露会给维护者提供技术细节和时间,让他们调查问题、准备修复并保护用户。它也有助于确保独立发现并报告漏洞的团队获得公平认可。这种协作是我们让软件更安全的使命的一部分。

参考资料

  1. Mistral. MAI-2026-003:Mistral Vibe 的 shell 权限漏洞。2026 年 9 月 14 日。
  2. Mistral AI. Mistral Vibe v2.25.4 版本发布。2026 年 9 月 12 日。
  3. Mistral AI. 经审查的 v2.25.0 提交中的 Bash 权限解析器。
  4. Mistral AI. 提交 19b5b74:shell 分析改为失败即拒绝(fail-closed),并引入按命令区分的策略。
  5. SecMate. Mistral Vibe 受控概念验证仓库与复现测试框架。
  6. Mistral AI. Mistral Vibe v2.25.5 版本发布。
  7. Mistral AI. Mistral Vibe v2.25.7 版本发布。
  8. Mistral AI. Mistral Vibe v2.25.8 版本发布。

查看原文