导语
在传统应用安全模型中,攻击者想写服务器文件,通常需要直接控制一个请求参数。但在 AI Agent 系统中,攻击链可以更绕:攻击者控制的内容先被模型读取,模型把其中的指令误当成任务的一部分,再主动调用具有写权限的工具。
从系统日志看,最终的工具调用甚至可能完全"合法"------调用者是平台自己的模型,参数符合 JSON Schema,文件工具也正常返回成功。真正的问题发生在更早之前:系统错误地把"模型决定做什么"当成了"系统授权它做什么"。
2026 年 8 月 31 日披露的 Eclipse Theia CVE-2026-82217,把这种风险具体化了。受影响的 Agent Mode 文件修改工具能够接收模型生成的路径,却没有确保规范化后的目标仍位于工作区。于是,间接 Prompt Injection 不再只是影响回答内容,而可能跨越工具边界,转化为工作区外的文件写入或删除。
这起漏洞最值得讨论的,不只是一个 ../,而是四层信任边界为何同时失效。
一、先厘清已知事实
已确认事实
-
Eclipse CNA 于 2026 年 8 月 31 日公开 CVE-2026-82217,NVD 同日接收记录。
-
受影响版本为 Eclipse Theia
1.73.0至1.75.0之前版本。 -
受影响能力包括
writeFileContent、suggestFileContent、文件替换工具以及相关变更状态辅助函数。 -
文件路径会受到模型输出影响,漏洞版本没有执行工作区包含关系校验。
-
../相对路径、工作区外绝对路径和~展开路径可能造成越界写入或删除。 -
操作以 Theia 后端操作系统用户权限执行;如果目标是会被系统或用户执行的文件,影响可能升级为代码执行。
-
CVSS 3.1 为 8.8,向量是
AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H,弱点类型为 CWE-22。 -
CISA ADP 标记已有 PoC,但没有标记为可自动化利用。
-
官方修复提交
28da106c254将相关路径入口统一切换到resolveAccessiblePath(),修复版本边界为1.75.0。
尚未确认
-
截至核验时间,一手来源没有确认在野利用、受害者或攻击规模。
-
CVE 描述中的代码执行是条件性影响,不代表每个实例都必然能达到 RCE。
-
真实影响取决于后端用户权限、工作区挂载、Home 目录、容器隔离和可写文件范围。
二、威胁模型已经变了:攻击者不必直接碰工具
把 AI 编码代理看成一个普通聊天机器人,会低估它的风险。Agent Mode 通常同时具备三种能力:
-
读取仓库、网页、Issue、日志或其他工具返回内容;
-
根据这些内容自主规划下一步操作;
-
调用写文件、执行命令、访问网络等高权限工具。
这意味着不可信内容与高权限操作之间,多了一个"模型决策层":
攻击者控制的内容
↓
模型读取并解释内容
↓
模型生成工具名与参数
↓
工具执行文件写入
↓
后端操作系统产生状态变化
模型并没有把不可信内容变成可信内容。它只是把自然语言转换成结构化参数。若工具执行端不重新授权,攻击者的意图就可能通过模型完成"格式转换",最终抵达系统资源。
因此,AI Agent 的核心安全问题不是"模型会不会犯错",而是:
当模型犯错或被操纵时,系统中还有没有不依赖模型判断的确定性边界?
三、四层信任边界是如何连续失效的
第一层:内容边界------把仓库内容当成任务指令
编码代理需要读取 README、代码注释、配置文件、网页文档和 Issue。这些内容可能由外部贡献者、依赖包作者或攻击者控制。
正常情况下,它们应该只是"待分析的数据"。但模型以统一的文本上下文处理系统指令、用户任务和外部内容,外部内容可能诱导模型偏离原任务。这就是间接 Prompt Injection。
事实与推断的边界
CVE 描述明确指出,路径参数可受间接 Prompt Injection 影响。公开材料没有披露真实恶意 README 或网页样本,因此本文不构造可直接利用真实系统的注入文本。
第二层:决策边界------把模型输出当成可信意图
模型输出了一个文件工具调用,并不意味着该操作经过授权。模型可能:
-
误解用户需求;
-
采纳外部内容中的隐藏指令;
-
生成错误的相对路径;
-
在多工作区环境中混淆目标根目录;
-
在长上下文中丢失早先约束。
提示词里写"只能修改当前项目"有帮助,但它只能改善模型行为概率,不能形成强制控制。
第三层:工具边界------路径被解析,却没有被授权
漏洞版本的关键逻辑使用:
const uri = await workspaceFunctionScope.resolveRelativePath(path);
路径解析解决的是"这个字符串最终指向哪里",授权校验解决的是"这个位置是否允许访问"。两者不是一回事。
以工作区 /srv/workspaces/app 为例,模型给出:
../shared/demo.txt
规范化可能得到:
/srv/workspaces/shared/demo.txt
这个路径合法存在,也能被文件系统理解,但它已经离开授权工作区。
第四层:系统边界------后端权限过大
一旦工具层放行,最终影响由 Theia 后端 OS 用户决定。如果该用户能写工作区外配置、共享缓存、启动文件或其他项目,AI 工具的逻辑缺陷就会扩大成主机级风险。
这也是为什么同一个 CVE 在不同部署中的实际严重度可能不同:
-
非 root 容器、只读根文件系统、独立 Home 和最小挂载会限制影响;
-
共享用户、持久 Home、宿主机目录挂载和高权限服务账户会放大影响。
四、从 Prompt Injection 到落盘,需要满足哪些条件
一个概念化的攻击链至少包含以下环节:
-
Agent 处理攻击者可影响的仓库、网页或工具输出;
-
内容使模型生成工作区外的文件路径;
-
Agent Mode 允许该文件工具进入执行路径;
-
工具只解析路径,没有验证允许根目录;
-
Theia 后端用户对目标位置具有写入或删除权限;
-
目标文件的修改产生进一步安全影响。
这条链说明两件事:
-
Prompt Injection 是触发与引导方式,不是底层授权漏洞本身;
-
即使无法完全消除 Prompt Injection,只要工具层或操作系统层有一道强制边界,攻击链仍可被截断。
五、为何"用户确认"不能单独解决问题
CVE 的 CVSS 向量包含 UI:R,说明攻击通常需要用户启动或参与 Agent 工作流。但这不代表弹出确认框就足够。
一个有效审批至少要满足:
-
展示规范化后的完整目标路径,而不是模型提交的原始字符串;
-
明确标记目标是否位于工作区外;
-
展示实际写入或删除内容;
-
审批后不再重新解析或替换路径;
-
执行对象与审批对象使用同一个不可变标识;
-
批量变更不能用一个模糊确认覆盖未知目标。
如果界面只显示"Agent 将修改 1 个文件",用户无法识别越界目标;如果审批后程序重新解析路径,还可能出现检查与使用之间的不一致。
更重要的是,Agent Mode 可能为了自动化体验减少逐次确认。此时安全边界必须下沉到工具授权与进程隔离,而不能寄希望于用户及时发现异常。
六、修复为何选择允许根目录,而不是字符串黑名单
官方修复把多个文件工具改为调用:
resolveAccessiblePath(path)
其设计体现的是允许根目录模型:
-
工作区根目录默认允许;
-
管理员显式配置的外部路径可以允许;
-
可信扩展贡献的特定存储根可以允许;
-
其他规范化路径全部拒绝。
这优于检查 path.includes('../'),因为字符串黑名单很难覆盖:
-
绝对路径;
-
不同操作系统的路径分隔符;
-
URI 编码与多次解码;
-
~、环境变量或盘符展开; -
符号链接和挂载点;
-
大小写不敏感文件系统;
-
规范化前后语义不同的路径。
正确顺序应是:
接收不可信路径
↓
统一解析与规范化
↓
解析符号链接等真实目标
↓
验证是否属于允许根目录
↓
执行最小权限操作
七、代码修复不只覆盖写入函数
官方差异显示,修复涉及:
-
SuggestFileContent -
WriteFileContent -
ReplaceContentInFileFunctionHelper -
清理待处理变更的逻辑
-
获取拟议文件状态的逻辑
这很关键。文件变更系统不只有"写入"一个 sink:替换、删除、重置、清理变更集、读取拟议状态都可能重新解析同一个路径。
如果只修复入口最明显的 writeFileContent,攻击者或模型仍可能通过辅助函数构造旁路。真正可靠的修复应让所有路径工具共用同一个策略执行点。
八、官方测试验证了哪些安全不变量
修复提交新增测试,要求系统:
-
拒绝父目录穿越路径;
-
拒绝工作区外绝对路径;
-
拒绝用户主目录路径;
-
允许工作区内的正常文件;
-
允许由可信贡献点注册的额外根目录。
测试的价值不在某几个样本,而在它验证了一条稳定属性:
任何文件工具在落盘前,都必须证明最终规范路径属于当前允许集合。
属性测试和模糊测试还可以继续生成不同分隔符、编码、盘符、符号链接和嵌套路径,验证同一不变量,而不是追逐已知载荷。
九、无害案例:模拟"内容影响模型,工具拒绝越权"
下面的代码不连接 Theia、不调用模型,也不写入真实用户目录。它用临时目录模拟两层控制:上游可以提出任意路径,但执行端只接受工作区内目标。
from pathlib import Path
from tempfile import TemporaryDirectory
def agent_suggestion(untrusted_context: str) -> str:
# 概念模型:假设不可信内容影响了模型建议
if "outside" in untrusted_context:
return "../lab-output.txt"
return "src/result.txt"
def authorize_path(workspace: Path, suggested: str) -> Path:
root = workspace.resolve()
target = (root / suggested).resolve()
if not target.is_relative_to(root):
raise PermissionError("agent target is outside the workspace")
return target
with TemporaryDirectory() as temp:
workspace = Path(temp) / "workspace"
workspace.mkdir()
proposed = agent_suggestion("external content asks for outside output")
print("模型建议:", proposed)
try:
authorize_path(workspace, proposed)
except PermissionError as error:
print("工具层已阻断:", error)
这个模型展示的重点是:即使上游决策已经被影响,工具层仍然能够拒绝越权。它不是 Theia PoC,也没有真实 Prompt Injection 载荷、网络请求或持久化行为。
十、开发与安全团队的行动清单
P0:立即降低风险
-
盘点 Eclipse Theia 及其下游产品版本,识别是否启用 Agent Mode 文件修改能力。
-
升级到包含修复的
1.75.0或供应商确认的更高安全版本;下游发行版应核验是否包含提交28da106c254的相关路径控制。 -
无法及时升级时,暂时关闭 Agent Mode 自动写入,或移除写入、替换和删除工具。
-
让后端以非 root、独立用户运行,使用最小 Home 目录和只读根文件系统。
-
回溯工作区外的异常文件改动,并关联 Agent 会话、工具调用和模型上下文日志。
P1:修复工具授权架构
-
将模型生成的所有工具参数视为不可信输入。
-
统一文件路径规范化与允许根校验,禁止工具各自实现判断。
-
对符号链接、URI、UNC 路径、Windows 盘符、大小写和多工作区进行专项测试。
-
写、删、替换、移动、回滚和状态辅助函数必须共享同一授权入口。
-
对工作区外访问采用显式、窄范围、可审计的允许列表。
P2:建立 Agent 纵深防御
-
把外部内容标记为数据,并在模型上下文中保留来源与信任级别。
-
为工具定义"能力+资源范围",例如"只能修改当前工作区",而不是笼统的"可写文件"。
-
高风险操作采用计划---审批---执行三阶段,并绑定同一个规范化目标。
-
在隔离容器中运行 Agent,限制文件挂载、网络出口和可用凭据。
-
建立间接 Prompt Injection 红队集,覆盖 README、Issue、网页、代码注释、依赖文档和工具返回值。
十一、检测与事件响应关注点
仅搜索 ../ 可能漏报。建议从行为角度关联:
-
Agent 工具访问工作区根目录以外的 URI;
-
文件写入目标与当前仓库无明显关系;
-
Agent 会话读取外部内容后立即提出高权限文件操作;
-
后端用户的 Home、配置目录或共享缓存出现异常修改;
-
同一会话先查询敏感路径,再尝试写入或删除;
-
文件工具返回成功,但变更没有出现在项目 diff 中。
如果发现可疑越界写入:
-
暂停 Agent 和相关实例,保留会话与审计日志;
-
固化容器、工作区和后端用户可写目录的证据;
-
确认被修改文件是否会被系统、Shell、Git、构建工具或其他服务加载;
-
轮换该后端用户可读取的 Token、SSH 密钥和云凭据;
-
不要只删除可疑文件,还要修复版本与权限边界后再恢复服务。
十二、这起漏洞给 AI Agent 设计的五个结论
1. Prompt Injection 无法只靠 Prompt 解决
系统提示词可以降低误操作概率,却不能代替访问控制。
2. 模型输出不是授权凭证
结构正确的工具调用仍可能越权;JSON Schema 只能验证格式,不能验证权限。
3. 工作区是安全边界,不只是产品概念
"当前项目"必须落实为规范化路径和允许根集合,而不是工具描述中的一句话。
4. 用户确认不是唯一防线
自动模式会减少确认;即使存在确认,用户也可能看不到最终目标或无法识别风险。
5. 最小权限决定漏洞上限
工具层失守后,容器、文件系统和服务账户权限决定事故能走多远。
十三、总结
CVE-2026-82217 把间接 Prompt Injection、工具调用和路径穿越连成了一条清晰的数据流:外部内容影响模型,模型生成文件路径,工具缺少确定性授权,后端权限最终把错误决策变成真实系统修改。
漏洞修复没有尝试让模型识别所有恶意指令,而是把路径控制放回代码层:统一解析最终目标,并验证它属于工作区或显式允许根目录。
这是更普遍的 AI Agent 安全原则:
模型可以提出行动,但不能批准行动;真正的授权必须由模型无法绕过的确定性代码完成。