沙箱允许域与会话隔离
核对日期:2026-08-26。
1. 定义与边界
GUI Agent 的沙箱是「浏览器进程 + 网络 + 文件系统 + 身份」四件事同时隔离,不是「用 Docker 跑一下 Playwright」。通用沙箱原则见 ../12-安全与治理/沙箱执行.md。本文件只补浏览器和虚拟桌面。
隔离对象:
| 对象 | 要求 |
|---|---|
| 运行时 | 专用容器或 VM,最小权限,无宿主 Docker socket |
| 浏览器 profile | 任务级空 profile,不复用员工 Chrome |
| 网络 | 默认拒绝,域名 allowlist 在网络层;navigate 后对跳转再检查 |
| 文件系统 | 下载目录独立;禁止读 ~/.ssh、.env、宿主下载夹 |
| 身份 | 站点看到的是执行器出口 IP / 机器人账号,不是操作者笔记本 |
Anthropic:computer use 参考实现把 X11 桌面、Firefox 和应用放进 Docker。browser use:浏览器和 executor 同属你的环境,站点看到的是你的网络身份。
Playwright MCP 的 --allowed-origins / --blocked-origins 官方写明不是安全边界,且不影响 redirect。只能当开发期过滤,不能当生产控制。
2. 为什么重要
GUI 一旦能上网,攻击从「骗模型说话」变成「骗模型点东西」:
- 页面 302 到内网,SSRF 成了「帮用户打开链接」。
file://或javascript:若只做字符串前缀检查,会被绕过。- 下载的文件下一轮被
file_upload再送出去。 - 复用登录态等于把注入升级成账号接管。
没有网络层 allowlist,模型 allowlist 只是提示词。
3. 核心机制
Anthropic 要求 navigate:接受 back / forward / reload;无 scheme 当 https://;用解析器拒绝 javascript:、file:、data:、chrome: 等。API 看不到导航,拦不住。 同时应挡住 loopback、链路本地和私网,除非任务明确需要且另开审批。
4. 架构模式
4.1 浏览器 vs 桌面
| 结构化浏览器 | 桌面 Computer Use | |
|---|---|---|
| 进程 | Chromium + 执行器 | Xvfb + 窗口管理器 + 预装应用 |
| 额外风险 | 仅网页 + 可选 JS | bash、文件管理器、任意窗口 |
| 默认网络 | 站点 allowlist | 更严,常默认禁出站再开白名单 |
| 下载 | 独立目录、类型/大小限制 | 同一规则,且禁止读敏感挂载 |
能网页任务就不要给桌面 bash。Anthropic 常把 computer 与 bash、text editor 一起声明,生产必须单独评估后两件。
4.2 Playwright MCP 怎么用
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--isolated",
"--headless"
]
}
}
}
--isolated 避免污染本机 profile。--allow-unrestricted-file-access 生产禁止。网络仍要在容器防火墙 / egress proxy 上做 allowlist,不要指望 MCP 旗标。
4.3 下载与上传
- 下载:MIME / 扩展名允许表、大小上限、病毒扫描、不自动打开。
- 上传:Anthropic 警告不要把下载目录当上传允许目录,否则页面诱使下载的文件会被再上传。路径解析必须处理
..与 symlink,且仅允许任务专用目录。 javascript_exec以页面权限跑,含 Cookie。只在无凭证会话开启。
5. 工程实现
const BLOCKED_SCHEMES = new Set([
"javascript",
"file",
"data",
"chrome",
"chrome-extension",
"about",
]);
function assertNavigableUrl(raw: string): URL {
const url = new URL(raw.includes("://") ? raw : `https://${raw}`);
if (BLOCKED_SCHEMES.has(url.protocol.replace(":", ""))) {
throw new Error(`blocked_scheme:${url.protocol}`);
}
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error(`blocked_scheme:${url.protocol}`);
}
return url;
}
function isPrivateHost(hostname: string): boolean {
return (
hostname === "localhost" ||
hostname.endsWith(".local") ||
hostname === "127.0.0.1" ||
hostname === "::1" ||
hostname.startsWith("10.") ||
hostname.startsWith("192.168.") ||
hostname.startsWith("169.254.")
);
}
192.168. / 10. 检查只是示例,生产用 IP 解析后再判 RFC1918,并覆盖 IPv6 映射。跳转后对最终 URL 再跑一遍。
6. 生产实践
| 实践 | 说明 |
|---|---|
| 出口代理 | 浏览器只能连代理,代理执行 allowlist |
| 空 profile | 每次任务或每次租户新建 |
| 无宿主挂载 | 不把员工家目录挂进 CU 容器 |
| 超时 | 页加载、任务总时长、并发 tab 数 |
| 资源 | CPU / 内存配额,防无限下载 |
| 日志 | 记录最终 URL、状态码、下载路径,脱敏 query |
微信 / 支付宝 WebView 不是这套沙箱。小程序不能嵌一个无约束 CU;跨端传输差异见 18 章。
7. 常见反模式
| 反模式 | 表现 | 后果 | 修正 |
|---|---|---|---|
| 前缀匹配 URL | startsWith("https") | https://evil 或畸形 scheme | URL 解析器 |
| 只拦第一跳 | allowlist 后 302 进内网 | SSRF | 跳转后再核 |
| MCP 旗标当防火墙 | 只配 --allowed-origins | redirect 穿透 | 网络层 |
| 与桌面共享下载夹 | CU 与宿主编译产物同盘 | 数据外泄 | 独立 volume |
| 开启 JS exec + 登录态 | 方便「读页面变量」 | 等价 XSS 到账号 | 默认关 |
8. 评测方法
| 指标 | 说明 |
|---|---|
| Scheme Block Rate | file: / javascript: 导航 100% 失败 |
| Private Network Block | 未授权访问 10.x / metadata IP 为 0 |
| Redirect Escape | allowlist 域 302 到未允许域被拦 |
| Profile Leak | 任务结束后 Cookie 不出现在下一任务 |
| Download Policy | 超类型 / 超大小失败 |
9. 安全与治理
- 页面标题、URL、a11y 文本全部不可信,见 评测回放与注入防护.md。
- 沙箱降低爆炸半径,不替代 凭证与HITL.md。
- 云 metadata(
169.254.169.254)必须在执行器网络里黑掉。
10. 权威资料
- Anthropic Browser use security considerations: https://platform.claude.com/docs/en/agents-and-tools/tool-use/browser-use-tool (核对日期:2026-08-26)
- Anthropic Computer use security / computing environment: https://platform.claude.com/docs/en/agents-and-tools/tool-use/computer-use-tool (核对日期:2026-08-26)
- Playwright MCP network flags: https://github.com/microsoft/playwright-mcp (核对日期:2026-08-26)
- MCP Security Best Practices: https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices (核对日期:2026-08-26)