Skip to main content
CC Safety Net 分析智能体尝试运行的命令字符串。它能阻止已知的破坏性 Git 和文件系统操作,降低意外丢失数据的风险,但不是完整的安全方案。本页列出仍存在的残余限制,并说明何时应改用沙箱 产品范围很明确。它只对受支持的编码智能体工具调用做尽力而为的静态执行前检查。它不是操作系统沙箱或权限边界,也无法保护绕过已安装集成的命令。
Standard 模式对对抗性或动态输入只提供尽力保护,下文有几项属于放宽,strict 或 paranoid 模式会将其关闭;属于这种情况的条目都会明确说明。

命令分析限制

二进制文件内部行为

如果命令本身看不出破坏性操作,命令字符串分析就无法推断出来。some-tool --task destructive-cleanup 在 CC Safety Net 看来是无害的,因为它无法检查任意二进制文件在运行时做了什么。这类威胁请改用沙箱

未配置或不透明的命令代理

代你运行 shell 命令的工具(例如 rtk git reset --hard)只有在声明为透明包装器后才会被分析:
配置之后,分析会穿过包装器看到可见的子命令,因此内置规则和自定义规则rtk git reset --hard 的处理与对 git reset --hard 完全一致。没有内置的默认包装器。只配置你有意信任的包装器。保留命令(gitbusybox、内置分析命令、shell 包装器和解释器)不能注册为包装器。 这项限制只影响以下两类代理:
  • 不在 transparent_wrappers 中的代理不会展开。
  • 即使已配置,改写或隐藏子命令而不是执行可见子命令的代理也无法展开。
这两种情况下,只有顶层危险文本 fallback 扫描可能捕获命令,而该扫描并不完整。transparent_wrappers 位于 rule.json 中,因此某个范围的 rule.json 无法读取时,在修复之前该范围的包装器都会失效。见配置恢复

eval 和动态执行

在运行时构造并执行代码的命令无法完整分析,因为被执行的字符串在分析时并不出现在命令文本里:
CC Safety Net 会递归扫描 bash -c 和解释器的代码参数,但如果代码来自远程来源或由变量拼接而成,命令字符串分析就看不到其中的破坏性 payload。这是这种方法的根本限制。

解析器限制

解释器长格式标志

CC Safety Net 提取传给解释器 -c-e 标志的代码(适用于 pythonpython2python3noderubyperl),并扫描其中是否有内嵌的破坏性操作。对应的长格式--eval--execute--print--require)和附加的 =value 形式(--eval='code')并非在所有代码路径中都能识别。使用长格式时,代码参数可能不会被提取出来做递归分析。 如果你担心自己的环境中出现解释器绕过,请启用 paranoid interpreters 模式CC_SAFETY_NET_PARANOID_INTERPRETERS=1),它会一律阻止所有解释器单行命令,不论内容如何。

短选项附加值

捆绑短标志(例如 -rf)会正确拆为 { -r, -f }。但不同分析器对短选项的附加值形式(例如 -Cfoo,其中 foo-C 的值)处理不一致。阻止 -f 等标志时,如果它实际是 -Cfoo 等附加选项值的一部分,可能产生误报。 这一点在编写精确的自定义规则时最需要注意。如有疑问,请使用 strictparanoid 模式以获得更强的保护。

符号链接 TOCTOU 风险

rm -rf 目标分类会先把符号链接解析到规范目标,再判定路径是否危险。分析器解析路径与 shell 实际执行 rm 之间存在不可避免的**检查时间到使用时间(TOCTOU)**窗口。符号链接可能在此窗口内重新指向其他位置。 所有执行前命令分析工具都有这一固有限制。要彻底消除它,就得在内核中运行或拦截系统调用,这超出了 hook 的范围。paranoid rm 模式(CC_SAFETY_NET_PARANOID_RM=1)可为希望更激进地拦截的运维人员提供更严格的策略。

范围外保护

下列边界不属于 CC Safety Net 的覆盖目标。它们大多需要隔离而不是语义分析,属于另一个保护层。每一项对应的沙箱能力见 CC Safety Net 无法提供帮助的范围

敏感路径覆盖有界,不是通用读取边界

CC Safety Net 确实保护敏感路径。对内置敏感集合的读取会被阻止,这一集合包括 .env 及其变体、~/.ssh/id_*~/.aws~/.kube/config、编码 CLI 凭证存储等。用户配置的拒绝路径及其下的所有路径也会被阻止。保护覆盖受支持的 command、path、search 和 patch 形式,包括未知工具的 fallback 检查。 编码 CLI 覆盖分两层。Credential 层(身份验证令牌和凭证存储)默认启用。Config 层(settings 和 MCP 配置文件,智能体会在日常工作中编辑)默认关闭,需要在 secret_protection.overrides 中显式设置 "on"。Antigravity 唯一的规则(secret.cli.antigravity)位于需要主动开启的 config 层,因此它没有默认启用的 credential 规则。完整层级和各规则保护路径见机密保护参考 残余限制在于,它是针对受支持形式的有界模式集,而不是通用的读取边界:
  • 凭证所在文件的名称和扩展名不在模式列表中时,不会被识别。
  • Standard 模式允许对内置敏感路径做独立的仅元数据检查,例如 test -f ~/.ssh/id_rsafind ~/.ssh -type fls -la ~/.sshstat .envStrict 和 paranoid 会阻止这类探查。任何模式都不会放宽配置的拒绝路径。
  • policy.json 中把 secret_protection.enabled 设置为 false 会关闭整个阶段,包括拒绝路径。
如果需要限制所有读取而不是已识别集合,请使用沙箱

不提供完整文件系统隔离

CC Safety Net 在工具调用运行前拒绝它,但不会强制执行文件系统权限。阻止消息是给智能体的指导,并不等于对文件系统的完整强制执行。灾难性保护始终强制执行,包括递归删除根目录或主目录、受保护的 Git 元数据集合和两个范围的 policy.json;但当你需要完整保护而不是尽力拦截时,请使用可信写入代理、操作系统权限、沙箱或同等的运行时强制执行机制。

没有网络层

运行时评估不发出网络请求,防护管线也不检查或过滤出站流量。通过网络外泄数据、域名允许列表和容器边界都不在产品范围内,而这些正是沙箱的网络限制所要解决的问题。

通用攻击防护

阻止提示注入驱动的数据外泄、验证用户身份和强制容器边界都不在范围内。CC Safety Net 假定智能体的命令字符串不可信,但不会检测任意二进制文件内部的隐藏行为。

自定义规则配置不防篡改

防篡改覆盖两个范围的 policy.json:用户策略文件,以及分别从执行目录和配置目录解析出的项目策略文件。rule.json 和 rulebook 不在保护范围内。每个 rulebook 都是运行时在每次工具调用时重新读取的实时文件,因此能写入 rules 目录的智能体,从下一次调用起就能改变实际生效的内容。 rule.json 中删除来源条目不再是唯一无人拦截的改动。rule update 往已落盘的 rulebook.json 里写了什么,没有任何地方记录,因此改写该文件中某条规则的 matchreason,不会留下改动痕迹。加载时,运行时只校验文件是否符合 schema,以及 name 是否与来源一致,然后照单执行。这处改动会一直生效,直到下一次 rule update 覆盖该文件。是否保护 rule.json 是一项推迟的产品决策。 项目的 policy.json 有一处有意设下的边界。它受保护的目录链止于自身的 .cc-safety-net 目录,而用户策略文件的目录链覆盖其所在目录以及直到文件系统根目录的每一级上级目录。项目这一侧若继续向上,就会把项目目录及其所有上级目录都纳入保护。那些正是破坏性命令规则针对的路径,而策略保护先于它们运行,于是 rm -rf .find . -delete 会返回这道防护的通用原因,而不是它们本来的原因。

Hermes Agent 和 OpenClaw 覆盖边界

Hermes Agent 和 OpenClaw 集成只覆盖一组明确定义的工具和执行主机。这个集合之外的调用要么得不到判定,要么直接被阻止。下面列出这些边界。

Hermes Agent 只检查固定工具列表

托管 Hermes 插件只注册一个 pre_tool_call hook,并且只把四个工具转交分析:patchread_fileterminalwrite_file。调用其他 Hermes 工具不会转发,也不会得到任何判定。 你自己输入的 !command 同样在范围外。bang-shell 输入不会触发 pre_tool_call,而是交给 Hermes 自己的命令防护处理。CC Safety Net 只能看到模型生成的工具调用,看不到 Hermes 启动的每一个子进程。如果 Hermes 根本没有加载插件,就不会有任何阻止。只有 npx cc-safety-net doctor 会报告插件已存在但未启用。

OpenClaw 覆盖本地 Gateway 主机上的 exec

OpenClaw 插件只为规范的 exec 工具注册 before_tool_callapply_patch 以及 OpenClaw 的读取、写入、编辑文件工具都不受保护。带 toolKind 区分标记的 exec 事件同样得不到判定。这样就排除了与 exec 同名的其他工具,例如 Code Mode 的 JavaScript exec。它的 command 字段并未被证明能映射为 shell 命令。 执行主机分三种情况:
  • 没有 hosthost: "auto"host: "gateway"exec 调用会按本地 Gateway 调用分析,路径按智能体 workspace 解析。
  • 显式指定 host: "sandbox"host: "node" 的调用不会被分析,而是作为不受支持的形式直接阻止,因为没有测试能证明这些主机的路径映射是正确的。
  • 配置中的 tools.exec.host 默认值不会改变分析:插件只读取调用自身的 host 参数,因此即使默认值把调用路由到 nodesandbox,没有 host 的调用仍按本地 Gateway 调用分析。
残余缺口出在 auto 上:sandbox runtime 处于活动状态时,auto 调用在沙箱文件系统中运行,而路径规则仍然按 Gateway workspace 判定。命令规则不受影响;路径规则则可能针对错误的文件系统判定。 Codex-native relay 未经测试,因此不作任何保证:端到端实测驱动的是 OpenClaw 自己的智能体 runtime,无法证明 Codex-native 的 shell、patch 或 MCP 调用会如何处理。

两种集成都不支持 Windows

两种集成都假定 POSIX 状态布局。被移动过的状态目录按各宿主自身的解析方式处理:Hermes 使用 HERMES_HOME;OpenClaw 依次使用 OPENCLAW_STATE_DIROPENCLAW_CONFIG_PATH 所在目录;最后回退到 ~/.hermes~/.openclaw。Windows 的默认位置则不在此列:安装和检测在 Windows 上仍指向 POSIX 路径,因此 Hermes 安装会把插件写入 Hermes 不会读取的目录;OpenClaw 自己的 CLI 可以正确安装,但 doctor 会误报状态。

Codex 覆盖边界

Codex 的统一 exec 路径(在 macOS 和 Linux 上是默认的 shell 路径)会在命令打开会话时发送 PreToolUse 负载,但对 write_stdin 不发送任何负载。只有打开该会话的那条命令会被评估。模型随后输入到这个已在运行的交互式会话中的文本,会不经检查、也不留审计记录地直接到达 shell。 这个缺口无法从 hook 一侧填补:宿主不会为该调用发出事件,因此根本没有可供分析的内容。如果在你的环境中需要防范向运行中的会话注入,请用沙箱作为隔离层。

Grok Build 是 fail-open 的宿主

Grok Build hook 在设计上就是 fail open,宿主也没有提供 failClosed 开关。只有 stdout 上明确的 deny 才能阻止工具调用。hook 崩溃、超时或输出格式错误时,调用照常执行。 适配器仍会为自身的 fail-closed 情况输出明确的 deny,例如工具输入被截断或工作目录不可用。但在这个宿主上,如果失败导致适配器完全没有输出,它就无法阻止这次调用。如果这项残余风险在你的环境中值得关注,请用沙箱作为隔离层。

解决过期集成缓存

OpenCode 过期缓存

新版本发布后,OpenCode 的插件安装程序可能仍然提供缓存中过期的 cc-safety-net。如果更新未生效,请清除缓存并重新安装,见 OpenCode 安装步骤。运行 npx cc-safety-net doctor 可确认检测到的插件版本。

过期 npx 缓存(Antigravity CLI、Cursor、Grok Build、Hermes Agent、Kimi Code)

Antigravity CLI、Cursor、Grok Build 和 Kimi Code hook 以及 Hermes Agent 插件通过 npx -y cc-safety-net 运行,因此 npx 自身缓存也可能继续提供旧版本。安装这五个目标中的任何一个时,系统会先删除所有包含 cc-safety-net 的 npx 缓存条目(_npx/*/node_modules/cc-safety-net),因此直接重新安装就能用上新版本,无需手动清理缓存。安装其他目标不会触及此缓存。

过期 bunx 缓存

bunx 把每个包的缓存放在操作系统临时目录下,因此 bunx cc-safety-net 也可能用到旧版本。每次运行 cc-safety-net update 都会清除其中属于你自己的 cc-safety-net 条目,即使一个集成都没有安装也一样。只有一个条目会保留:从 bunx 启动的 update 不会删除自己正在运行的那个条目,因为删除使用中的文件在 Windows 上会失败。该条目会按 bun 自己的 manifest TTL 重新解析。

破坏性命令漏过时的处理方法

先确认你遇到的是已记录的边界,还是意料之外的情况:
explain 命令会显示 CC Safety Net 评估该命令的完整逐步分析,其中包括有效安全级别,因此你可以区分已记录的 standard 模式放宽和真正的缺口。更完整的逐症状排查流程见故障排除
真实跟踪不会自动变得可以安全分享。脱敏只覆盖已识别的凭证形式;你提供的命令文本、解析后的 token、包含主目录在内的绝对路径以及策略文件路径都会原样保留。请使用占位凭证复现,并在粘贴到任何地方之前先检查输出。
然后选择报告渠道:
  • 规则尚未阻止的命令形式属于覆盖缺口,这是公开 bug。请提交 GitHub issue,说明命令形式,不要提供可直接粘贴的 payload。
  • 机密泄漏、预期目录外写入,以及供应链或软件包完整性问题则走私密披露渠道。
两种流程和完整的分类标准见安全策略
最后修改于 2026年8月31日