Agent 明明运行在受限环境里,为什么还有可能访问宿主机?

设置 workspace-write 后,Agent 本应只能修改项目目录。本文用可视化链路解释旧 Bubblewrap 配置为何仍能看到宿主进程、/proc 路径如何暴露另一份文件视图,以及怎样升级到含修复的版本、完成无破坏检查,并确认网络和其他沙箱后端仍有哪些边界。

你把 /srv/app 交给编码 Agent,并把权限设成 workspace-write。你的预期很简单:

  • /srv/app 里的代码、锁文件和测试产物可以修改;
  • /etc、其他项目和宿主服务的文件保持只读。

但旧版 DeepSeek Harness 的 Bubblewrap 配置漏掉了一层进程隔离。受限命令仍能看到宿主机进程,而 Linux 的 /proc 又能把一个进程看到的文件系统暴露出来。两件事连在一起,某些主机权限配置下,Agent 可能越过“只写工作目录”这条边界。

先看完整链路,再进入 Linux 细节:

workspace-write、宿主进程、proc 路径与越界写入风险之间的四步关系

图 1:问题不在 workspace-write 单独失效,而在旧 profile 仍能看到宿主 PID,给 /proc 留下了跨边界入口。

DeepSeek Harness 已在 2026 年 8 月 21 日发布的 dsh-v0.1.1-rc.1 中修复这个问题。如果线上还在 0.1.0-rc.8,或者固定在更早的提交,需要检查实际版本和沙箱后端,而不只是确认 Agent 能正常启动。

workspace-write 只回答“哪里能写”

workspace-write 只告诉 Harness 哪些路径允许修改,不等于运行命令的进程已经与宿主机完全隔离。

在 Linux 上,Harness 可以用 Bubblewrap 执行 Agent 发出的 Shell 命令。Bubblewrap 是用 namespace(命名空间)和挂载参数组装沙箱的底层工具。它不会自动替调用方决定“哪些进程应该可见”或“网络是否可用”;隔离强度取决于启动时传入的参数。

旧 profile 确实把宿主根目录绑定为只读,并为工作区建立写入允许列表。缺口在另一个地方:它挂载了新的 /proc,却让沙箱与宿主共用 PID namespace。PID namespace 决定一个进程能看到哪些进程。两边共用时,沙箱里的 /proc 仍可能列出宿主 PID。

这就是为什么文章会从一个工作目录权限,走到 Linux 进程隔离:写入规则已经存在,但执行这些写入的进程还看得到不该出现在沙箱视图里的宿主进程。

为什么一个 /proc 路径可能把 Agent 带到宿主机

Linux 会为每个可见进程建立 /proc/<pid>/ 目录。假设宿主服务的 PID 是 4182/proc/4182/root 不是一份普通文件,它代表的是“进程 4182 眼中的根目录”。

不同进程可能看到不同的挂载内容。对 Agent 来说,/ 经过 Bubblewrap 处理;对宿主服务来说,/ 仍是宿主自己的文件视图。Linux 手册因此特别说明:/proc/<pid>/root 不只是普通软链接,它展示目标进程自己的文件系统视图,包括 namespace 和单独挂载的内容。cwdfdexe 等 procfs“魔法链接”也可能产生类似的跨视图路径。

所以旧配置下的关键不是“Agent 知道了一个奇怪路径”,而是:它先看见宿主 PID,再通过这个 PID 找到宿主进程看到的根目录。当访问控制允许跟随链接时,路径就可能绕过只读宿主根绑定和 workspace-write 允许列表。

这里必须保留“可能”。Linux 会做 ptrace 权限检查,结果还受内核设置、进程凭据、容器配置和目标进程是否允许转储影响。有些主机会拒绝访问,有些同用户进程可能可达。官方没有公布 CVE、CVSS 分数或完整受影响版本表,这也不是所有使用 Bubblewrap 的应用都存在的通用“容器逃逸”。

修复后,沙箱里的 /proc 不再显示宿主进程

修复提交为每个 Bubblewrap profile 增加 --unshare-pid,也就是创建私有 PID namespace,并为它挂载匹配的 /proc

DeepSeek Harness 修复前共用宿主 PID namespace,修复后使用私有 PID namespace 的对比

图 2:修复后,Agent 仍能管理自己的子进程,但宿主进程及其 procfs 路径不再出现在沙箱视图中。

这项修复没有删除 /proc。受限命令仍能查看、终止并等待自己启动的子进程;区别是它看不到宿主 PID,也就没有对应的 /proc/4182/root 可以跟随。

官方端到端测试同时覆盖 read-onlyworkspace-write:沙箱内外的 PID namespace 标识必须不同;通过 /proc/1/root 写宿主目标必须失败;沙箱内的子进程管理仍要成功。

如果主机无法创建 PID namespace,Harness 的功能探测会拒绝 Bubblewrap,转而选择 Landlock,而不是悄悄取消沙箱继续运行。Landlock 仍能限制文件访问,但不会像修复后的 Bubblewrap 一样隐藏宿主进程,因此检查结果必须结合实际后端解释。

先确认版本,再做无破坏检查

截至 2026 年 8 月 24 日,npm 已发布 0.1.1-rc.2,并且该版本包含上面的修复提交。通过 npx 启动时,可以固定到这个版本:

npx @deepseek-ai/[email protected] web

如果使用源码构建或内部镜像,检查构建是否包含提交 fe12e047327938012031dc1ec795cbab8afe2cf8,不要只看“latest”标签。0.1.1-rc.2 仍是开发者预览版,升级前应保留配置,并回归测试插件、Shell 和文件权限。

如果团队不准备自己维护 Host,SandBase Agents 现在也支持把 DeepSeek Harness 选作 Agent 运行引擎。公开的 DeepSeek Harness runtime 模块显示,这条路径运行固定版本的 DSH headless runtime,并把任务放在独立的 E2B Sandbox 中。这里要区分两层边界:--unshare-pid 修复针对 DeepSeek Harness 自带的 Bubblewrap profile;SandBase 托管运行依赖的是外层 E2B 隔离。无论选哪一种,部署记录都应写明实际 runtime 版本和 sandbox provider,不能只写“已开启沙箱”。

随后分别在宿主终端和 Agent 的受限 Shell 中执行:

readlink /proc/self/ns/pid

这条命令只读取当前进程的 PID namespace 标识,不会写宿主文件。修复后的 Bubblewrap profile 中,两边标识应该不同。如果相同,先检查本次命令实际走了 Bubblewrap、Landlock 还是其他后端;不要为了验证而在生产机上照搬写入 /proc/1/root 的攻击代码。

升级以后,别把它当成完整虚拟机

这次修复没有限制网络。Agent 能访问哪些域名、能否连接内网服务,仍取决于外层网络策略。

它也没有改变其他后端的进程视图。--unshare-pid 修复的是 Bubblewrap;Landlock 和 macOS Seatbelt 仍保留宿主进程可见性。部署记录如果只写“已开启 sandbox”,值班工程师仍不知道真正启用了哪条边界。

对仍运行 0.1.0-rc.8 的部署,优先评估升级到 0.1.1-rc.2,然后执行上面的只读检查。暂时无法升级时,不要把陌生仓库、Issue 或网页内容直接交给能执行 Shell 的 Agent;缩小工作目录和可用凭据,并把任务放进可丢弃的外层环境。

workspace-write 是否兑现,最终不只取决于配置里的一行权限名,还取决于执行它的后端是否隔离了正确的 namespace。

Sources