跳到主要内容
SecondHome

把危险关进笼子:沙箱的边界三问、放置拓扑与状态余波

7 分钟进阶7aL13 p.19-25 ↗录像 ↗支撑材料 4 篇

沙箱是 lecture-07 安全主线的工程支柱(L13 p.19-25)。定义(p.19):隔离环境,限制程序可访问/可执行的范围——允许任务文件与运行代码,策略阻断私有文件与其他服务。边界三问(p.20):文件系统与进程(能访问/控制什么)、网络(能联系谁、能做什么)、资源限额(算力/存储/最长运行时间)。放置拓扑(p.21):agent 整体进沙箱 vs agent 在外、工具调用越界进沙箱(OpenShell 示例);铁律=访问规则与执行机制必须置于 agent 控制之外。共享状态陷阱(p.22):状态活得比写入它的运行更久——Cline 事故复盘(对应 p.6):issue 处理运行写入中毒文件→运行结束→发布运行 Restore 共享状态→发布被劫持;PocketOS 反例(p.4)=staging 任务持生产删除权的执行面/授权面双重错位。四要求(p.23):快速启动、强隔离、冻结与重载、易用。选型(p.24-25):本地 Docker/Apptainer(容器、共享宿主内核)与 QEMU(VM、guest OS)vs 云 Modal/E2B;Tian Pan(2026-03-09)六级光谱(0 无沙箱起):容器→Seccomp-BPF→gVisor(I/O 密集开销 10-30%)→Firecracker microVM(冷启动约 125ms、内存 <5MiB、快照恢复约 28ms)→WASM。警示:IsolateGPT(圣路易斯华盛顿大学,NDSS 2025)显示无隔离 agent 的敏感数据可经共享「对话」上下文而非代码执行外泄——沙箱管不住语义层泄漏。

Cline 有过一次被完整复盘的发布劫持,起点只是 agent 顺手往共享工作区写了一个构建脚本。

让 agent 干活,就得允许它运行代码、读写文件,这两样是几乎所有 agent 安全事故的来源。沙箱(sandbox)是讲义 L13 p.19 给出的核心对策。

但开一个 Docker 远不等于做了隔离。边界、拓扑、状态残留,三层决策各对应一类真实事故。本篇沿 L13 p.19-25 把它们各自钻透。

一、先问对问题:隔离边界三问

讲义 L13 p.19 的定义只有一句:沙箱是一种隔离环境(isolated environment),限制程序能访问与能执行的范围。

落到场景上,沙箱内允许两件事:访问任务相关文件、运行代码;同时被策略(policy)明确阻断两件事:访问私有文件、联系其他服务。

定义不难,难在范围怎么划。讲义 L13 p.20 把这道题拆成三问,任何沙箱方案都可以拿去逐条过堂:

  1. 文件系统与进程:能访问哪些文件?能控制哪些进程?
  2. 网络:能联系哪些服务?联系上之后允许做什么?
  3. 资源限额:算力、存储、最长运行时间各给多少?

这三问把隔离从形容词变成检查清单。只挡文件不挡出站的网络、只限 CPU 不限运行时长的方案,在第二、三问面前过不了堂。

反过来,L13 p.4 的 PocketOS 反例败在三问开口之前:staging 任务握着生产环境的删除权。这是执行面与授权面的双重错位,沙箱强度不是症结。

二、笼子放哪:两种拓扑与一条铁律

边界想清楚后是拓扑(topology)问题:笼子套在谁身上。讲义 L13 p.21 画了两种。要么 agent 整体进沙箱,推理循环与全部工具都活在隔离环境里;要么 agent 留在外面,每次工具调用(tool call)越界进入受控的执行环境。

两种拓扑各有适用面,但讲义立了一条不让步的铁律:访问规则与执行机制必须置于 agent 的控制之外。agent 可以发起请求,不能自批请求。

讲义点的示例是 OpenShell 架构:agent 在沙箱外运行,命令一律交给沙箱内的执行器按策略裁决。

为什么规则必须活在 agent 够不到的地方

沙箱防的不只是模型被攻破后作恶,更常见的是模型被说服后作恶:提示注入(prompt injection)之下,agent 自己就是攻击载荷。

若访问规则由 agent 侧持有或可协商,一次注入就能把它改宽。拓扑二要求工具调用越界进沙箱,为的就是把策略引擎放进 agent 无法触达的层。

三、活得比运行更久:共享状态陷阱

边界与拓扑都对,还有一类攻击来自时间维度。讲义 L13 p.22 的警告是:共享状态(shared state)可以活得比写入它的那次运行更久。对应 L13 p.6 的 Cline 事故复盘把这条时间线完整摊开:

user: 任务一:处理 issue,修复仓库里的 bugassistant: 定位并修改代码;顺手向共享工作区写入了一个构建脚本tool: 写入成功 ——「中毒」文件进入共享状态。本次运行到此正常结束,什么也没发生user: 任务二(数日后):发布新版本assistant: 按惯例恢复(Restore)上一次运行留下的共享状态,直接进入构建流程tool: 中毒文件随共享状态一同恢复,并在构建中执行 —— 发布任务被劫持Observation: 写入发生在一次被信任的运行里,引爆发生在另一次无辜的运行里;若沙箱随运行销毁、或恢复前先检查状态,这条链条在任何一环都可为零

沙箱的生命周期必须覆盖状态的生命周期。下一节四要求里的「冻结与重载」既保存文件与运行态、支持从检查点恢复,也打开新的风险面:恢复的不只是你的文件,还可能是投毒者埋下的东西。

四、好沙箱的四个要求与一条技术光谱

讲义 L13 p.23 给生产级沙箱定了四个要求:

  • 快速启动:新环境低延迟就绪。
  • 强隔离:与宿主及其他运行分离。
  • 冻结与重载:保存 / 恢复文件与运行态。
  • 易用:创建、配置、检查、停止都是简单接口。

L13 p.24 先把选型分成本地与云:本地方案如 Docker、Apptainer、QEMU,自己管理配置与生命周期;云方案如 Modal、E2B,在厂商机器上通过 API 创建与控制沙箱。本地方案再按 L13 p.25 的架构分层:

技术架构定位
Docker容器本地开发默认选项,工具链最广
Apptainer容器适合共享集群,以本人用户运行、免 root
QEMU虚拟机跑完整客户操作系统(guest OS)

容器与 VM 的分水岭在内核:容器共享宿主内核,VM 自带客户内核。

启动快、开销低、生态广 —— 但宿主内核仍是双方共用的边界,隔离强度依赖内核自身的访问控制。

内核级隔离,逃逸要多破一层 —— 代价是镜像更重、启动更慢,需要用 microVM 把这笔开销压回来。

隔离强度其实是一条光谱。Tian Pan(2026)把它排成六级(0–5):无沙箱 → 容器 → Seccomp-BPF → gVisor → Firecracker microVM → WASM。

这几组数字把「强隔离」与「快速启动」的张力变成可算的账:gVisor 对 I/O 密集负载的开销为 10-30%;Firecracker microVM 冷启动约 125ms、内存占用 <5MiB、快照恢复约 28ms。

越往右隔离越硬、代价越高,但 microVM 已把代价压进 agent 循环可承受的量级。四个要求不再互斥,按风险匹配隔离深度即可。

与本讲的连接

伴读把沙箱放在 lecture-07 安全主线的工程防线一节。本篇把 L13 p.19-25 压成三步决策:先拿 p.20 的边界三问逐格设防,再定 p.21 的拓扑、守住规则在 agent 之外这条铁律,最后按 p.23 的四要求去 p.25 的光谱上选隔离深度。还要记住 p.22 的警告:共享状态的余波可能比任何一次运行都长。

四张资料卡分别对应:

  • m7-openshell-arch:拓扑二的参考实现。
  • m7-modal-sandbox:云端沙箱的 API 形状。
  • m7-tianpan-sandbox:六级光谱的全文。
  • m7-swe-misbehavior:给越界行为建了分类。

最后补一剂清醒剂。IsolateGPT(圣路易斯华盛顿大学,NDSS 2025)显示,无隔离的 LLM agent 里,敏感数据会经共享对话上下文外泄,而非经代码执行。沙箱拦得住系统调用,拦不住模型在回答里复述密钥这类语义层泄漏。

SWE-MISBEHAVIOR(2026)用 7.4K 人机协同合成样本给 coding agent 的 11 种失当行为建了首个分类与评测,覆盖代码生成、文件管理、系统交互三层动作空间。这张地图就是三问要逐格设防的清单。

沙箱是必要条件,从来不是充分条件。

本节论文与规范

本节资料

AI 生成 · 仅供参考,与课程方无关。选中正文里的任何一段也能直接问我(解释一下 / 举个例子)。

本详解以 CMU 11-768 AI Agents (Fall 2026) 课程大纲为参考框架独立撰写,AI 辅助起草、人工抽审。 涉及的官方课件、论文与课程材料版权归原所有方,讲义为站内镜像、其余外链原文出处; 观点与文字(除标注引用外)为作者原创。