AI 工程
唯一没有沙箱的那一家,把"没有沙箱"写进了官方文档
Claude Code、Cursor、Codex、OpenCode 四款 coding agent 在沙箱与安全拦截上的对照:边界放在哪一层,失效时谁能看见。
唯一没有沙箱的那一家,把“没有沙箱”写进了官方文档
TL;DR: Claude Code、Cursor、Codex、OpenCode 在上下文压缩、检索、记忆和 subagent 调度上已经出现明显收敛,真正拉开差异的是执行边界。本文对照的四款工具里,OpenCode 明确把沙箱防护列在安全承诺之外;另外三家提供不同程度的 OS 级隔离,但实际覆盖范围并不等于“所有 agent 行为都在沙箱里”。已经披露的漏洞也说明,安全边界不仅会从内核层失效,还可能败在默认语义、代理解析和沙箱外工具对配置文件的信任上。比“有没有沙箱”更值得问的是:边界究竟画在哪里,以及边界失效之后用户能不能知道。
Claude Code、OpenCode、Cursor、Codex 四款 coding agent harness,在压缩、检索、记忆和 subagent 调度上的设计表面上越来越像。但到了沙箱和安全拦截,差异突然变得明显:边界到底放在哪一层?哪些操作真正受到 OS 级隔离?边界失效之后,用户又能不能看见?
这种差异和产品形态有一定对应关系:Claude Code 是本地 CLI,Cursor 横跨 IDE 与云端,Codex 更接近 SaaS 企业平台,OpenCode 则是开源社区项目。不过,仅凭产品形态不能推出安全设计背后的动机。能可靠比较的,还是各家的公开文档、源码和已经披露的漏洞。
一份把“没有沙箱”写进安全文档的 SECURITY.md
OpenCode 的 SECURITY.md 很直接:它把沙箱相关防护列进了 Out of Scope。也就是说,这类攻击不属于项目当前公开承诺的安全边界。
这里需要控制解读的强度。公开材料能够支持的是“OpenCode 明确披露了这部分不在安全承诺范围内”,但不足以进一步推导出“维护者出于某种安全哲学,主动决定永远不要沙箱”。除非维护者另有明确立场声明,否则后者只是推测。
这个区别很重要。Coding agent 的安全讨论经常停留在“有没有沙箱”,但真正影响风险的是两个更具体的问题:沙箱究竟覆盖什么,以及没有覆盖什么是否被写清楚。
要理解这种差异,可以先看四家在其他几个核心能力上的设计。很多地方其实已经高度收敛,到了安全边界才真正分叉。
压缩与检索已经基本收敛
四家面对的是同一个硬约束:上下文窗口有限。因此自动压缩加手动压缩已经成为共同设计,这部分没有太大分歧。
检索也在向 agentic search 收敛,即让模型自己决定查什么、沿什么路径继续搜索。Claude Code 曾经尝试 embedding 和本地向量库,后来根据创始人的公开说明转向 agentic search,理由包括效果以及安全、隐私和数据过期问题。OpenCode 和 Codex 没有采用这条向量检索路线。Cursor 则保留了向量检索式能力,这更像是云端 IDE 产品形态带来的设计差异,没有必要简单解释成领先或落后。
真正有意思的是两个实现细节。
Codex 的思路不是不断把旧内容压进同一个窗口,而是可以主动换窗。Cursor 则把历史对话当成能够重新读取的内容:信息不一定要在第一次压缩时决定最终形态,需要的时候还可以重新进入上下文。
这两个设计指向同一件事:解决上下文不足,不只有“把历史压得更薄”这一条路。另一种办法,是让历史内容保持可寻址,在需要的时候重新读取。
同一份 agents.md,四家的加载语义并不相同
Agentic coding 已经出现了一份跨工具规则文件标准:agents.md。它由 OpenAI Codex、Amp、Jules(Google)、Cursor、Factory 协作发起,发起者名单里没有 Anthropic。
Claude Code 目前也没有原生采用这份标准。Claude Code 的记忆文档描述的是它自己的记忆与规则加载机制。至于这意味着“没有跟进外部标准”,还是有意经营自己的工具生态,现有材料不足以判断。
对用户而言,更实际的问题是加载语义:同一个 agents.md,在支持它的工具里会成为默认输入,但在 Claude Code 中不能假设它会自动生效。写下规则,并不等于每个 coding agent 都会读取这份规则。
Cursor 还多了一层产品状态带来的影响:它的记忆行为与 Privacy Mode 相关,隐私模式会改变记忆的使用方式。这也说明所谓“记忆层”并不是一个独立、静态的本地存储机制,它会受到产品权限和隐私设计的直接影响。
Subagent 架构相似,差异藏在通信和资源约束里
Subagent 调度反而是四家最一致的地方之一:子 agent 使用独立上下文执行任务,再把结果摘要返回主 agent。至少从公开实现和文档来看,核心架构都在向“独立上下文 + 摘要回传”靠拢。
真正的差异在通信能力和资源限制上。
Anthropic 在 multi-agent research system 工程博客中公布过具体的成本倍数,而另外几家更多是定性描述。不过这组数字来自 Anthropic 自家网页研究系统在 BrowseComp 上的内部数据,不能直接外推成 coding subagent 的通用成本规律。
Codex 则提供了一个更少见的运行时能力。从 openai/codex 源码中的 control.rs、execution.rs 可以看到,它支持在子 agent 运行过程中继续向其发送消息;本文对照的另外三款工具采用的更多是“任务发出后等待结果返回”的模式。
另一方面,Codex 的并发上限直接作为资源约束写在实现中。其他三家的公开实现没有表现出同样形式的硬编码上限。架构看起来相似,但实际运行时可以怎样控制子 agent,已经开始分化。
真正拉开差异的是沙箱边界
回到安全问题。
在本文对照的四款工具里,OpenCode 的公开安全文档明确不承诺沙箱防护;另外三家都有某种 OS 级执行隔离,但“有沙箱”并不意味着 agent 的所有能力都处在同一个内核边界之内。
这也是很多产品描述最容易产生误解的地方。用户看到“sandbox”之后,很容易把它理解成“agent 的所有文件、网络和工具行为都已经被隔离”。实际上,每家的沙箱只覆盖特定执行路径,其他能力可能仍然依赖权限询问、宿主侧代理或沙箱之外的可信组件。
OpenCode:至少把边界写在了明处
回到开篇的 SECURITY.md,能够确定的事实很简单:OpenCode 主动把沙箱相关防护排除在当前安全承诺之外。
这里不需要替维护者补充一套“哲学”。从用户视角看,更有价值的是这份披露本身:读完安全文档之后,至少知道不能把系统沙箱当成 OpenCode 已经提供的安全边界。
换句话说,它的问题不是“沙箱承诺到底覆盖到哪”,而是文档已经告诉你,这部分需要由使用者自己承担。
Claude Code、Cursor、Codex 都有隔离,但覆盖范围不同
Claude Code 提供 OS 级隔离,同时使用宿主侧代理限制网络域名。但它的 OS 级隔离主要覆盖 Bash 工具及其子进程;Read、Write、WebFetch、MCP servers、hooks 等能力并不因此自动获得同样的内核隔离,而更多依赖权限和各自的安全机制。
这正是“产品有沙箱”和“所有工具调用都在沙箱中”之间的差别。
Cursor 的隔离分布在本地和云端两套执行环境。本地采用“沙箱优先”的设计:macOS 使用 Seatbelt,Linux 使用 Landlock + seccomp,并带有 bubblewrap 兜底。云端后台 agent 则运行在独立的云端环境中。
Codex 的平台覆盖更完整:macOS、Linux、Windows 都提供默认执行隔离,而且从公开实现可以看到较明显的 fail-closed 倾向。例如 glob 解析失败时会终止沙箱构建,而不是因为规则无法解析就直接放行。
因此,用一句“这三个都有沙箱”概括并没有太大分析价值。更准确的比较方式,是逐层看哪些进程、工具、网络访问和配置路径真正落在隔离范围里。后面几个漏洞恰好说明,问题经常出现在这些层之间的缝隙中。
漏洞数量不能直接拿来排安全名次
比较漏洞之前还需要处理一个证据偏差:公开披露的漏洞数量,不等于真实漏洞数量,更不等于产品安全水平。
闭源产品可能因为用户规模、企业价值和漏洞赏金而吸引更多研究者;开源项目披露较少,也不能据此推断攻击面更小。反过来也一样。
因此,这里不比较“四家谁被曝出的漏洞更多”,只看已经公开的案例分别击中了什么机制。真正有价值的是失效方式,而不是漏洞计数。
三个案例,分别打穿了三种边界
第一类问题出现在默认语义。
Claude Code 的网络 allowlist 配置 allowedDomains 曾出现过一个反直觉行为:用户配置 [],本意是“不允许任何域名”,系统却把它解释成“没有限制”。SecurityWeek 对这次绕过的报道显示,这不是用户配置错了,而是系统对空列表语义的处理与安全直觉相反。
第二类问题出现在解析器。
oddguan 的技术分析记录了 SOCKS5 代理中的 null-byte 解析缺陷,它能够绕过宿主侧代理的域名过滤,使 Claude Code 的网络 allowlist 失效并形成数据外泄路径。根据这份分析,该问题持续了 5.5 个月、跨 130 个版本,两次修复都属于 silent fix,没有公开公告。
这里尤其需要把边界说准确:失效的是宿主侧代理实现的网络 allowlist,不是 OS 级隔离本身。把进程限制在 localhost 的隔离仍然存在,只是负责控制目标域名的另一层防线被绕过。因此,不能把这个案例进一步改写成“Claude Code 的整个沙箱从未生效”。
第三类问题出现在沙箱内外的信任关系。
BleepingComputer 对 Pillar Security “Week of Sandbox Escapes”的报道涉及 Cursor 的三个漏洞,同时也涉及 Codex、Gemini CLI、Antigravity。报道描述的一类共同模式是:攻击者先在沙箱内写入配置或文件,再由沙箱外的受信任工具消费这些内容,于是执行路径跨出了原本的隔离边界。
这组材料也不能被包装成“三次独立验证”:Cursor 的三个漏洞来自 Pillar Security 同一次披露活动,是一次批量研究产出,而不是多个研究团队分别发现同一种缺陷。
三个案例分别错在默认语义、解析器和跨边界信任关系。它们共同说明,coding agent 的安全边界并不只存在于内核沙箱本身。只要权限配置、代理、解析器或者沙箱外的可信工具仍然参与决策,其中任何一层都可能成为实际攻击面。
云端隔离更强,不代表审批也更多
Cursor 的后台 agent 文档展示了另一个很有代表性的取舍:后台 agent 在云端隔离环境里执行,但运行过程中不会像本地交互式 agent 那样不断请求用户批准。
这不是简单的“安全加强”或“安全减弱”,而是把控制放到了不同位置。执行环境与本机隔离得更彻底,于是产品可以减少人工审批;与此同时,用户对单次操作的实时控制也相应减少。
所以,评价 coding agent 的安全机制时,最好不要只看“沙箱有多强”或者“审批有多严格”其中一个指标。隔离、权限、审批和自动化程度是一整套取舍,它们共同决定用户实际暴露的风险。
硬编码拦截和完全交给用户,是两个极端
危险操作拦截同样能看到两种完全不同的设计。
Claude Code 对 rm -rf / 这类操作提供硬编码拦截。官方沙箱文档说明,即使进入更激进的权限绕过模式,这类保护仍然存在。也就是说,有一部分安全规则不是用户配置,而是产品不允许轻易跨越的固定边界。
OpenCode 则没有对应的默认内置拦截。类似 rm -rf 的危险命令是否受到限制,取决于用户自己的环境和配置。
这两种模式不能简单归结成“哪一种一定更安全”。硬编码规则能够减少用户误操作,但只要安全系统存在多层组件,仍然可能因为语义、解析器或跨边界信任而失效;把控制权交给用户避免了制造“已经被系统保护”的错觉,却同时要求用户自己建立足够可靠的执行边界。
真正值得检查的,不是产品页面上有没有写 “sandbox”,而是更具体的几件事:哪些执行路径进入了 OS 级隔离,哪些仍依赖权限或宿主组件;默认拒绝规则在异常情况下是 fail-open 还是 fail-closed;沙箱内生成的文件会不会被沙箱外的可信工具继续执行;以及这些边界和已知失效是否被公开写清楚。
从这个角度看,OpenCode 最突出的地方并不是“没有沙箱”本身,而是它至少把这一限制明确写进了安全文档。对另外三家来说,沙箱确实提供了更强的执行隔离,但“有沙箱”仍然只是分析的起点,而不是安全结论。