AI 代理说“只改项目”,为何却能写进用户主目录?Eclipse Theia CVE-2026-82217 深度解析
导语
当 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 的文件修改工具,包括
writeFileContent、suggestFileContent、替换工具及相关状态辅助函数。 -
这些工具接收受模型输出影响的路径,却没有执行工作区边界校验。
-
父目录穿越、绝对路径和
~展开路径可使写入或删除动作逃出工作区,并继承 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:立即处理
-
盘点使用 Eclipse Theia 及其下游发行版的实例,识别是否启用了 AI Agent Mode。
-
将受影响版本升级到包含修复的
1.75.0或供应商确认的更高安全版本;对下游产品,应核对是否包含提交28da106c254的相关路径校验改动。 -
在无法立即升级时,暂时禁用 Agent Mode 自动文件写入,或移除文件修改工具能力。
-
将后端进程改为非 root 用户,使用独立、最小化的 Home 目录,并把工作区外文件系统设为只读。
-
检查后端用户可写目录近期出现的异常文件修改,重点关注工作区外的配置、启动和凭据相关目录。
P1:本周完成
-
对所有 AI 工具参数做数据流审计:文件路径、命令、URL、数据库查询、Git 引用和云资源标识都应视为不可信。
-
建立统一的路径授权库,禁止各工具自行拼接和判断路径。
-
先规范化、再授权;授权判断基于最终规范路径与允许根目录的包含关系。
-
同时验证符号链接、大小写差异、Windows 盘符、UNC 路径、URI 编码和
~展开。 -
为写入、替换、删除、重命名、回滚和状态查询等所有 sink 建立相同的测试矩阵。
P2:平台级治理
-
将工具权限从“允许文件系统”细化为“允许哪些根目录、哪些动作、哪些扩展名和最大写入量”。
-
对高影响操作采用“计划—审批—提交”模式,并确保用户看到的规范化目标路径与最终写入路径完全一致。
-
将模型建议的路径、规范化结果、授权决策和实际落盘结果写入不可篡改审计日志。
-
在 Agent 运行容器中启用只读根文件系统、最小挂载、无特权用户和网络出口限制。
-
把间接 Prompt Injection 测试加入 AI 红队:恶意 README、网页、Issue、代码注释和工具返回值都应覆盖。
九、安全评审时应问的十个问题
-
模型能调用哪些会改变系统状态的工具?
-
工具参数是否全部在执行端重新校验?
-
文件路径是否在规范化后再做边界检查?
-
是否存在多个路径解析函数,且安全能力不一致?
-
绝对路径、
..、~、符号链接和 URI 如何处理? -
写、删、改名、替换和回滚是否共享同一授权入口?
-
用户审批界面展示的是原始路径还是最终规范路径?
-
审批后到执行前,路径是否可能再次变化?
-
后端 OS 用户能写哪些工作区外目录?
-
如果代理被 Prompt Injection 操纵,确定性控制能否仍然阻断越权?
十、给 DevSecOps 的启示:把“代理权限”变成可测试的不变量
传统 SAST 容易发现 path.join(root, userInput) 一类模式,但 AI Agent 系统还需要更高层的安全不变量。
建议将下面四条写入设计文档和发布门禁:
不变量一:模型输出永远不拥有隐式信任
无论参数来自用户、模型还是可信提示词,执行端都必须做同样的授权。
不变量二:能力必须绑定资源范围
“可以写文件”过于宽泛。正确权限应是“可以在指定工作区根目录内修改文件”。
不变量三:所有同类 sink 共用一个策略入口
只修复 writeFileContent 不够,替换、删除和变更集辅助函数也必须经过同一门禁。
不变量四:审批对象必须与执行对象一致
展示给用户的路径、校验的路径和最终落盘路径必须是同一个规范化对象,避免审批后发生重解析或路径替换。
十一、总结
CVE-2026-82217 的底层弱点是熟悉的 CWE-22,但它出现在 AI 编码代理中后,攻击链发生了变化:攻击者可以先影响模型上下文,再让模型生成危险路径,最后借助自动文件工具把语义攻击落到真实系统权限上。
官方修复的关键不是让模型“更听话”,也不是在提示词里强调“不要离开工作区”,而是把所有路径工具统一放到确定性的允许根目录校验之后。
这也是 AI Agent 安全最重要的工程原则之一:
提示词负责引导行为,代码负责强制边界;任何高权限工具都不能把模型自律当成授权机制。
更多推荐


所有评论(0)