32.3 沙箱机制
生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~280k tokens,输出 ~9k tokens(本节)
当 AI Agent 被赋予执行命令、读写文件等"工具能力"后,一个核心问题浮出水面:如果 Agent 被提示词注入攻击劫持,它能造成多大的损害?OpenClaw 的沙箱系统通过 Docker 容器隔离来回答这个问题——将非主会话的工具执行限制在受控的容器环境中,即使 Agent 行为异常也无法触及宿主机。
32.3.1 沙箱设计:非主会话的 Docker 隔离(src/agents/sandbox.ts)
src/agents/sandbox.ts)沙箱模式
沙箱行为通过 agents.defaults.sandbox.mode 配置,有三种模式:
"off"
默认值。不使用沙箱,所有命令在宿主机执行
"non-main"
非主会话使用沙箱。主会话(Bot 所有者的 CLI 交互)不受限
"all"
所有会话都在沙箱中执行,包括主会话
"non-main" 是推荐的生产配置——它让 Bot 所有者保留完整的宿主机访问权限,同时将来自渠道(WhatsApp、Telegram 等)的会话隔离到容器中。
沙箱作用域
scope 决定了容器的生命周期粒度:
// src/agents/sandbox/types.ts
export type SandboxScope = "session" | "agent" | "shared";"session"
每个会话一个容器
最强隔离,不同会话完全独立
"agent"
每个 Agent 一个容器(默认)
同一 Agent 的多个会话共享容器
"shared"
所有 Agent 共享一个容器
最节约资源
32.3.2 沙箱配置解析(src/agents/sandbox/)
src/agents/sandbox/)双层配置合并
沙箱配置支持全局默认值和 Agent 级别覆盖的双层结构。resolveSandboxConfigForAgent 函数合并两层配置:
Docker 配置的安全默认值
resolveSandboxDockerConfig 应用了一系列安全加固默认值:
readOnlyRoot: true
根文件系统只读,防止修改系统文件
tmpfs: ["/tmp", "/var/tmp", "/run"]
临时目录使用内存文件系统,容器销毁即清除
network: "none"
完全禁用网络访问,防止数据外泄
capDrop: ["ALL"]
丢弃所有 Linux 能力(capabilities),最小权限
衍生解释:Linux Capabilities 是一种细粒度的特权划分机制,将传统的 root 超级用户权限拆分为 40+ 个独立的能力(如
CAP_NET_ADMIN管理网络、CAP_SYS_PTRACE调试进程等)。--cap-drop ALL丢弃所有能力,使容器内的进程即使以 root 运行也几乎没有特权操作能力。这是 Docker 安全加固的标准最佳实践。
32.3.3 沙箱路径管理(src/agents/sandbox-paths.ts)
src/agents/sandbox-paths.ts)路径逃逸防护
沙箱环境中最关键的安全问题之一是路径遍历攻击——Agent 可能试图通过 ../../etc/passwd 等路径访问沙箱根目录之外的文件。resolveSandboxPath 函数执行严格的路径验证:
符号链接防护
即使路径在字符串层面没有逃逸,攻击者仍可能通过**符号链接(symlink)**绕过——在沙箱内创建一个指向外部目录的符号链接。assertNoSymlink 函数逐层检查路径中的每个组件:
衍生解释:**TOCTOU(Time-of-check to Time-of-use)**是一类常见的安全漏洞——在检查文件属性和实际使用文件之间存在时间窗口,攻击者可以在此期间将正常文件替换为符号链接。OpenClaw 通过使用
lstat(不跟随符号链接的 stat)而非stat来减轻这一风险,但完整的 TOCTOU 防护通常需要操作系统级别的支持(如 Linux 的openat系统调用配合O_NOFOLLOW标志)。
Unicode 空格规范化
expandPath 函数还处理了一个容易被忽视的攻击向量——Unicode 不间断空格和其他特殊空白字符:
这防止攻击者使用特殊空白字符构造看起来合法但实际指向不同位置的路径。
32.3.4 Docker 沙箱容器
容器创建参数
buildSandboxCreateArgs 构建 docker create 命令的完整参数列表。除了前面提到的安全默认值,还有一个关键的安全标志:
衍生解释:
--security-opt no-new-privileges是 Linux 内核的PR_SET_NO_NEW_PRIVS标志。它确保容器内的进程(及其子进程)不能通过setuid、setgid等机制获取新的特权。即使容器内存在一个 setuid-root 的可执行文件,攻击者也无法利用它提升权限。这是 Docker 安全加固中最重要但最容易被遗忘的选项之一。
容器生命周期管理
ensureSandboxContainer 管理容器的完整生命周期——创建、复用、配置漂移检测:
配置漂移检测是一个重要的安全特性——当用户修改了沙箱配置(如从 network: "none" 改为 network: "bridge")后,旧容器可能仍在使用旧配置运行。系统通过配置哈希比对来检测这种情况:空闲容器自动重建,活跃容器发出警告。
工作区挂载
容器创建时会将工作区目录挂载到容器中,挂载方式取决于 workspaceAccess 配置:
"none"
沙箱独立目录 → /workspace
Agent 无法访问宿主机文件
"ro"
宿主机工作区 → /workspace:ro
只读访问宿主机文件
"rw"
宿主机工作区 → /workspace
读写访问宿主机文件
32.3.5 工具白名单 / 黑名单
沙箱工具策略
沙箱环境中不是所有工具都应该可用。resolveSandboxToolPolicyForAgent 解析三级优先级的工具策略:
默认策略
通配符匹配
工具名称支持通配符模式匹配:
**黑名单优先(deny-first)**策略确保了安全性——即使白名单中包含某个工具,如果它同时出现在黑名单中也会被拒绝。
32.3.5 文件系统写入安全加固(v2026.3.9 新增)
v2026.3.9 对沙箱内的文件写入操作进行了全面的安全加固,引入了固定写入(Pinned Write)机制和原子替换(Atomic Replace)操作。
固定写入助手
fs-pinned-write-helper.ts(src/infra/fs-pinned-write-helper.ts)通过 Python 子进程执行原子文件操作,防止写入过程中的竞争条件:
沙箱变异助手
fs-bridge-mutation-helper.ts(src/agents/sandbox/fs-bridge-mutation-helper.ts)构建安全的命令计划,将写入操作封装为可审计的脚本:
这套机制的核心安全保证是:临时写入文件绝不会在允许的挂载点之外物化(Materialize)。即使攻击者在写入过程中操纵了符号链接或替换了父目录,O_NOFOLLOW + O_DIRECTORY 标志和写入后的 dev:ino 校验也能检测到异常。
本节小结
三种沙箱模式:
off(关闭)、non-main(推荐,仅隔离外部会话)、all(全部隔离)。三种作用域:
session(最强隔离)、agent(默认,同 Agent 共享)、shared(全局共享)。安全默认值:只读根文件系统、无网络、丢弃所有 Linux 能力、禁止特权提升。
路径安全:路径逃逸检测 + 符号链接检查 + Unicode 空格规范化,防止多种路径遍历攻击。
配置漂移检测:通过配置哈希比对发现容器与配置不一致,空闲容器自动重建。
工具策略:Agent 级别 > 全局 > 默认的三级优先级,黑名单优先于白名单。
默认拒绝:浏览器、渠道发送、Gateway 管理等敏感工具在沙箱中默认被禁用。
Last updated