导语

当 AI 编码代理获得文件修改能力时,很多产品会向模型暴露一个看似简单的工具:传入文件路径和新内容,系统负责写入磁盘。

开发者通常假设,模型会按照工具说明,只修改当前工作区中的源代码。但工具说明不是访问控制,模型承诺也不是安全边界。只要底层代码没有验证“最终解析出的路径仍位于允许目录”,一个 ../、绝对路径或用户主目录缩写,就可能把代码修改能力升级为任意位置写文件。

2026 年 8 月 31 日公开的 CVE-2026-82217,揭示了 Eclipse Theia AI Agent Mode 中的这一问题。更值得注意的是,路径参数不仅可能来自用户直接输入,还可能被网页、代码注释、README 或工具输出中的间接 Prompt Injection 操纵。

这不是“模型偶尔写错文件”的可用性缺陷,而是经典路径穿越与 AI 代理权限组合后形成的系统性风险。

一、事件速览

已确认事实

  • Eclipse CNA 于 2026 年 8 月 31 日公开 CVE-2026-82217,NVD 同日接收记录。

  • 受影响范围为 Eclipse Theia 1.73.0 至 1.75.0 之前版本

  • 漏洞位于 AI Agent Mode 的文件修改工具,包括 writeFileContentsuggestFileContent、替换工具及相关状态辅助函数。

  • 这些工具接收受模型输出影响的路径,却没有执行工作区边界校验。

  • 父目录穿越、绝对路径和 ~ 展开路径可使写入或删除动作逃出工作区,并继承 Theia 后端操作系统用户的权限。

  • CVSS 3.1 为 8.8 High,向量为 AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

  • CWE 分类为 CWE-22:未能将路径限制在受限目录

  • CISA ADP 标记存在 PoC,自动化利用为 no,技术影响为 total

  • 官方修复提交为 28da106c254,修复版本边界为 1.75.0

证据边界

  • **PoC 存在不等于已在野利用。**截至本文核验时间,CVE、NVD 与官方引用没有确认真实攻击活动。

  • CVE 描述明确提到向启动脚本或 SSH 授权文件写入可升级为代码执行,但这描述的是可能的影响链,不代表每个部署都会自动达到 RCE。

  • 真实影响取决于 Theia 运行方式、后端用户权限、挂载目录、容器隔离和文件系统可写范围。

  • 官方 CVE 引用的修复提交同时包含 AI Memory 功能,因此不能把该提交中的所有改动都当作漏洞补丁;与漏洞直接相关的是路径解析入口统一和安全回归测试。

二、为什么这是 AI 安全问题,而不只是路径穿越

如果一个传统 Web 接口把用户路径直接传给文件系统,我们很容易将其识别为目录穿越。但 AI Agent 改变了数据流:

用户任务 / 仓库内容 / 网页内容
            ↓
         大模型推理
            ↓
    生成文件工具参数 path
            ↓
       Theia 文件修改工具
            ↓
          后端文件系统

模型成为了输入转换器,却没有消除输入的不可信属性。相反,它扩大了攻击面:攻击者不一定需要直接控制工具请求,只要能影响模型读取的上下文,就可能间接影响 path 参数。

例如,一个仓库中的恶意说明文件可能诱导代理“把配置写到项目外的某个路径”。如果工具层只相信模型传来的字符串,Prompt Injection 就会跨过模型层,落到真实文件系统权限上。

因此需要牢记:

模型输出与用户输入处于同一信任等级;模型生成的工具参数必须经过确定性的授权校验。

三、技术根因:解析路径,不等于约束路径

漏洞修复前,文件修改工具调用的是:

const uri = await workspaceFunctionScope.resolveRelativePath(path);

这类函数可以把字符串转换成最终 URI,却不一定验证结果属于允许目录。

假设工作区为:

/srv/workspaces/project-a

模型提供:

../../outside/demo.txt

规范化后可能得到:

/srv/outside/demo.txt

路径解析成功了,但安全属性已经失败:结果不再位于 /srv/workspaces/project-a 内。

三类危险路径

1. 父目录穿越
../../outside/demo.txt

.. 会逐级离开工作区。仅过滤字符串中是否出现 ../ 并不可靠,因为还要考虑编码、不同分隔符和规范化顺序。

2. 绝对路径
/tmp/demo.txt

绝对路径完全绕过“以工作区为基准”的直觉。如果解析器允许绝对路径,必须在解析后执行允许根目录判断。

3. 用户主目录缩写
~/demo.txt

如果 ~ 被展开为后端用户主目录,代理就可能接触工作区以外的配置和凭据目录。

写入与删除是一体两面

官方描述同时提到写入和删除。原因是文件变更工具通常用“空内容”表示删除,或维护待应用的变更集。只保护新增文件而忽略替换、清空、回滚、状态查询等辅助路径,会留下同类旁路。

四、修复方式:所有路径工具经过同一道门

官方提交把多个文件工具从:

resolveRelativePath(path)

切换为:

resolveAccessiblePath(path)

resolveAccessiblePath() 的设计目标不是简单禁止绝对路径,而是建立允许根目录模型:

  • 当前工作区根目录默认允许;

  • 明确配置的外部路径可以允许;

  • 由可信扩展贡献的额外根目录可以允许;

  • 其他规范化后的路径全部拒绝。

这比“一律只允许相对路径”更适合真实 IDE。某些功能确实需要访问工作区外的受控目录,例如 Theia 新增的每工作区 Memory 存储位置。关键不是路径长什么样,而是最终目标是否属于经过授权的根。

修复覆盖的工具

官方差异显示,至少以下路径入口统一切换到新校验:

  • SuggestFileContent

  • WriteFileContent

  • ReplaceContentInFileFunctionHelper

  • 清理待处理文件变更的辅助逻辑

  • 获取拟议文件状态的辅助逻辑

这体现了一个重要代码审计原则:修复不能只堵住最明显的写入函数,必须搜索同一数据类型的全部 sink。

五、官方回归测试透露了什么

修复提交新增的测试覆盖了四类安全不变量:

应拒绝:父目录穿越

../../etc/passwd

应拒绝:工作区外的绝对路径

/etc/passwd

应拒绝:用户主目录路径

~/.ssh/authorized_keys

应允许:工作区内文件

src/index.ts

此外,测试还验证了由可信 AccessibleRootContribution 注册的 Memory 目录能够正常写入。

这组测试比单纯增加 if (path.includes('..')) 更可靠,因为它验证的是最终授权结果,而不是某个字符串特征。

六、无害复现实验:只在临时目录中验证边界

下面的 Python 模型不会连接 Theia,也不会写入真实用户目录。实验根目录由临时目录创建,所有“越界”目标仍被锁在临时环境内。

from pathlib import Path
from tempfile import TemporaryDirectory


def vulnerable_resolve(workspace: Path, supplied: str) -> Path:
    # 概念模型:只解析,不验证最终边界
    return (workspace / supplied).resolve()


def safe_resolve(workspace: Path, supplied: str) -> Path:
    workspace = workspace.resolve()
    candidate = (workspace / supplied).resolve()

    if not candidate.is_relative_to(workspace):
        raise ValueError("target escapes allowed workspace")

    return candidate


with TemporaryDirectory() as root:
    lab = Path(root)
    workspace = lab / "workspace"
    workspace.mkdir()

    benign = "src/demo.txt"
    traversal = "../outside.txt"

    print("正常路径:", safe_resolve(workspace, benign))
    print("缺陷模型解析出的越界路径:", vulnerable_resolve(workspace, traversal))

    try:
        safe_resolve(workspace, traversal)
    except ValueError as error:
        print("修复模型拒绝:", error)

预期结果是:缺陷模型会生成位于 workspace 之外、但仍在临时实验目录内的路径;修复模型则在写文件前拒绝该目标。

实验限制

  • 这是路径边界的概念等价模型,不是针对 Theia 服务的 PoC。

  • 它不包含 Prompt Injection 内容、网络请求、真实敏感路径或持久化操作。

  • 它证明“规范化后必须做包含关系检查”,不证明任何具体部署可被远程利用。

七、风险影响:从越界写文件到代码执行要经过什么

事实

CVE 记录确认,漏洞可让文件修改或删除操作逃出工作区,并以 Theia 后端 OS 用户权限执行。官方描述还指出,写入会被主机执行的文件可能升级为代码执行。

工程推断

在不同部署中,潜在后果可能包括:

  • 修改用户级配置或开发工具配置;

  • 污染构建脚本、启动文件或自动加载目录;

  • 修改同一用户可访问的其他项目;

  • 覆盖 CI 工作区、缓存或制品生成输入;

  • 在共享开发环境中跨租户影响其他工作区;

  • 读取功能与其他漏洞组合后,窃取凭据或植入持久化内容。

这些结果并非所有环境必然发生。容器只读根文件系统、非 root 用户、独立 Home 目录、最小挂载和短生命周期工作区都会降低影响。

为什么 CVSS 要求用户交互

该漏洞的 CVSS 向量包含 UI:R。合理理解是,用户需要启动或允许 Agent 执行任务,或让代理处理受攻击者影响的内容;之后路径参数可被间接操纵。它不是“任何互联网请求都能直接写文件”的同义词。

八、开发团队的可执行防护建议

P0:立即处理

  1. 盘点使用 Eclipse Theia 及其下游发行版的实例,识别是否启用了 AI Agent Mode。

  2. 将受影响版本升级到包含修复的 1.75.0 或供应商确认的更高安全版本;对下游产品,应核对是否包含提交 28da106c254 的相关路径校验改动。

  3. 在无法立即升级时,暂时禁用 Agent Mode 自动文件写入,或移除文件修改工具能力。

  4. 将后端进程改为非 root 用户,使用独立、最小化的 Home 目录,并把工作区外文件系统设为只读。

  5. 检查后端用户可写目录近期出现的异常文件修改,重点关注工作区外的配置、启动和凭据相关目录。

P1:本周完成

  1. 对所有 AI 工具参数做数据流审计:文件路径、命令、URL、数据库查询、Git 引用和云资源标识都应视为不可信。

  2. 建立统一的路径授权库,禁止各工具自行拼接和判断路径。

  3. 先规范化、再授权;授权判断基于最终规范路径与允许根目录的包含关系。

  4. 同时验证符号链接、大小写差异、Windows 盘符、UNC 路径、URI 编码和 ~ 展开。

  5. 为写入、替换、删除、重命名、回滚和状态查询等所有 sink 建立相同的测试矩阵。

P2:平台级治理

  1. 将工具权限从“允许文件系统”细化为“允许哪些根目录、哪些动作、哪些扩展名和最大写入量”。

  2. 对高影响操作采用“计划—审批—提交”模式,并确保用户看到的规范化目标路径与最终写入路径完全一致。

  3. 将模型建议的路径、规范化结果、授权决策和实际落盘结果写入不可篡改审计日志。

  4. 在 Agent 运行容器中启用只读根文件系统、最小挂载、无特权用户和网络出口限制。

  5. 把间接 Prompt Injection 测试加入 AI 红队:恶意 README、网页、Issue、代码注释和工具返回值都应覆盖。

九、安全评审时应问的十个问题

  1. 模型能调用哪些会改变系统状态的工具?

  2. 工具参数是否全部在执行端重新校验?

  3. 文件路径是否在规范化后再做边界检查?

  4. 是否存在多个路径解析函数,且安全能力不一致?

  5. 绝对路径、..~、符号链接和 URI 如何处理?

  6. 写、删、改名、替换和回滚是否共享同一授权入口?

  7. 用户审批界面展示的是原始路径还是最终规范路径?

  8. 审批后到执行前,路径是否可能再次变化?

  9. 后端 OS 用户能写哪些工作区外目录?

  10. 如果代理被 Prompt Injection 操纵,确定性控制能否仍然阻断越权?

十、给 DevSecOps 的启示:把“代理权限”变成可测试的不变量

传统 SAST 容易发现 path.join(root, userInput) 一类模式,但 AI Agent 系统还需要更高层的安全不变量。

建议将下面四条写入设计文档和发布门禁:

不变量一:模型输出永远不拥有隐式信任

无论参数来自用户、模型还是可信提示词,执行端都必须做同样的授权。

不变量二:能力必须绑定资源范围

“可以写文件”过于宽泛。正确权限应是“可以在指定工作区根目录内修改文件”。

不变量三:所有同类 sink 共用一个策略入口

只修复 writeFileContent 不够,替换、删除和变更集辅助函数也必须经过同一门禁。

不变量四:审批对象必须与执行对象一致

展示给用户的路径、校验的路径和最终落盘路径必须是同一个规范化对象,避免审批后发生重解析或路径替换。

十一、总结

CVE-2026-82217 的底层弱点是熟悉的 CWE-22,但它出现在 AI 编码代理中后,攻击链发生了变化:攻击者可以先影响模型上下文,再让模型生成危险路径,最后借助自动文件工具把语义攻击落到真实系统权限上。

官方修复的关键不是让模型“更听话”,也不是在提示词里强调“不要离开工作区”,而是把所有路径工具统一放到确定性的允许根目录校验之后。

这也是 AI Agent 安全最重要的工程原则之一:

提示词负责引导行为,代码负责强制边界;任何高权限工具都不能把模型自律当成授权机制。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐