Agent 护栏:2026 年 10 月,编程工具集体转向安全
学习目标:读懂 2026 年 10 月第一周三大编程 Agent 的发版重点,理解"给会自己跑的 Agent 系安全带"这件事在工程上具体长什么样,并把可复用的护栏原则落进自己的团队。
预计时间:40 分钟
难度等级:⭐⭐⭐
最后更新:2026-10-23
先说结论
这一周的版本更新,关键词不是"模型更聪明",而是**"让会自己跑的 Agent 别把机器弄坏"**。
- Claude Code 从 2.1.290 到 2.1.296 连发 7 个版本,其中 2.1.292 一次性修掉四个沙箱/权限绕过,2.1.294、2.1.295、2.1.296 继续补 hook 的 fail-open 漏洞。
- Codex CLI 把 GPT-6.1 Sol 设为默认,同时把 Daybreak 从"默认出现"改成显式 opt-in——能力越强,默认越收敛。
- Cursor 让手机能看、能发消息给本机运行的 Agent,但企业版默认关闭,由管理员在 Org settings 打开。
- Grok Build 1.0.50 让
grok worktree rm对"使用中/有未保存改动"的 worktree 必须加-f。
看起来是四件不相干的事,其实是同一个转折点:Agent 从"帮你补全"变成"替你执行",产品的竞争力开始从模型质量转向权限模型。
为什么护栏突然成了主线
过去一年,编程 Agent 的能力边界扩张得非常快:执行任意 shell、读写仓库、跑子代理、联网抓页面、连 MCP 服务、接管浏览器。每一次能力扩张,都同时扩大了三样东西:
| 能力 | 顺带扩大的风险面 | 典型失败模式 |
|---|---|---|
| 自主执行 shell | 主机文件系统 | 一条 rm、一次重定向写文件 |
| 读写仓库 | 版本库完整性 | 覆盖未提交改动、破坏远端分支 |
| 子代理 / 后台任务 | 权限判定的传播 | 子代理绕过主会话的 deny 规则 |
| 联网与 MCP | 数据外流 | 把 ~/.ssh、.env 内容带进请求 |
| 长会话 + 便宜模型 | 单位时间内的操作量 | 错误被放大一百倍,且没人盯着 |
再叠加两个 2026 年的新变量:
- 推理成本继续下探。Claude Code 2.1.293 把 Haiku 5.5 变成默认 Haiku 模型,1M 上下文,$0.10/$0.50 per Mtok(超过 100K 的 prompt 按 $0.50/$2.50 计),意味着"随手开十个子代理"从奢侈变成默认行为。
- 会话越跑越长。长会话意味着更多工具调用、更多后台任务、更多"人已经离开键盘"的时间窗口。
对你意味着什么:你不能再把权限配置当成装完就忘的初始化步骤。它和 CI 配置一样,是需要版本管理、需要评审、需要回归测试的工程资产。
Claude Code 的安全周:2.1.290 → 2.1.296
先把这一周的时间线摊开,再逐个看修复内容。
| 版本 | 日期 | 主题 |
|---|---|---|
| 2.1.290 | 10-05 | hook API 扩展,修代理、图片会话、WebFetch 静默截断 |
| 2.1.291 | 10-06 | 修 2.1.290 / 2.1.288 引入的两个回归 |
| 2.1.292 | 10-06 | 安全修复集中营:四个沙箱/权限绕过 + --marketplace |
| 2.1.293 | 10-07 | Haiku 5.5 成为默认 Haiku 模型 |
| 2.1.294 | 10-08 | 修 prompt/agent hooks 反向放行 |
| 2.1.295 | 10-08 | hook 支持 onFailure: "block"(fail-closed) |
| 2.1.296 | 10-09 | 修 managed hook 批准被阻断调用;拒绝破坏非 UTF-8 文件的编辑 |
2.1.290 / 2.1.291:先收拾地基
2.1.290 扩展了 mod hook 的上下文(工具调用、权限判断),同时修了三类基础问题:
- 拒绝某个 beta header(非 400 状态码,或多个 beta 一起)的代理/网关导致请求全失败;
- 几百张图片的长会话卡在 "unprocessable by the model";
- WebFetch 静默丢弃 100,000 字符之后的页面内容,现在会告诉你漏了多少,并支持
offset续读。
2.1.291 紧接着修了两个回归:云会话丢失权限提示的回答、退出时丢失会话最后几条消息。
对你意味着什么:静默截断是最危险的一类 bug——模型以为读完了整页,基于半截内容做决策,而你完全无从察觉。任何"读取类"工具都必须报告"我没读完",而不是安静地返回一个看起来正常的结果。这条原则可以直接搬到你自己写的 MCP 工具里。
2.1.292:四个绕过,四种不同的错误
这一版的修复清单里,安全项单独拎出来看:
| 绕过 | 具体行为 | 根因类型 |
|---|---|---|
| 1 | 沙箱内命令能读取 /ultrareview 上传在 ~/.claude/seed-admin 下的暂存文件副本 | 沙箱边界没覆盖"系统自己产生的临时副本" |
| 2 | managed 的 read-deny 路径会话中途出现或改指向时,没有撤销其中的项目授权、没有结束凭据注入 | 策略是加载时算的,不是每次判断时算的 |
| 3 | 从网络(UNC)路径读取文件时,PreToolUse hook 的批准与 auto mode 跳过了权限提示 | 权限判定按路径形态分叉,漏了一条分支 |
| 4 | 磁盘上被篡改的 server-managed settings 缓存,能在设置拉取失败时关掉或顶掉内置 policy 插件 | 信任了本地缓存,且失败时 fail-open |
同一版本还修了:macOS/Windows 上 notebook/PDF 读取通过"读取中途被替换的链接"返回未批准的文件;claude plugin 系列命令在组织 managed settings 尚未加载时就开始执行。
再加上一个正向改动:claude plugin install --marketplace <source> 会自动添加市场,但走与 claude plugin marketplace add 相同的策略检查。
对你意味着什么:
- 沙箱不是"把进程关进笼子"就完了。笼子里如果是自己搬进去的数据——上传暂存、缓存的设置、凭据文件——那就等于没关。
- 策略必须在每次工具调用时重新求值。会话中途出现的 deny 路径、中途变化的符号链接,都是真实攻击面。
- 安装插件这类"会写配置文件"的操作,必须和手动操作共用一套检查。为省一步而开的快捷通道,就是下一个绕过点。
2.1.293:便宜模型 = 更大面积
Haiku 5.5 成为 Anthropic API 上默认的 Haiku 模型:1M 上下文,$0.10/$0.50 per Mtok,prompt 超过 100K 后按 $0.50/$2.50 计。
成本下降的直接影响不是"省钱",而是调用量上升。子代理、后台压缩、摘要、分类这些高频路径会默认跑起来,而它们每一个都可能带着工具权限。
便宜的推理会让"多开几个 Agent"变成默认操作。护栏的默认值必须比成本下降的速度更快变严。
2.1.294:自然语言不是 ACL
这一版修的是一条很容易被忽略的洞:
prompt和agenthooks 被写成"指令式"(例如 "Block commands that...")时,放行了本该阻断的操作。
也就是说,你用自然语言写了一条安全规则,hook 里的模型理解成了"这是一段说明",于是返回 allow。同时这一版改进了 Stop / SubagentStop 上 prompt hook 的判定,减少 Claude 提前停下。
对你意味着什么:任何"让模型判断是否放行"的 hook,本质上是一个概率组件。它可以作为纵深防御的一层,但不能作为唯一的准入控制。确定性的 deny 规则(路径、命令前缀、工具名)必须写在模型判断之外。
2.1.295:fail-closed 成为可配置项
这一版加的是这一周最重要的原语:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "./scripts/guard.sh",
"onFailure": "block"
}
]
}
]
}
}onFailure: "block" 的语义:hook 无法启动、超时、或以非预期退出码结束时,阻断该操作,而不是放行。
同一版本还加了:网关 upstream 支持 models 白名单,且故障转移后依然生效;claude plugin install/enable/disable/marketplace add 在写入的 settings 文件加载失败时给警告;子代理最多从 skills 字段预载 32 个技能。
对你意味着什么:
- 这是安全工程里最基本也最常被违反的一条:失败必须收敛到拒绝。默认 fail-open 的设计,会在磁盘满、依赖缺失、超时的时候悄悄变成"全部允许"。
- 网关模型白名单跨 failover 生效,是同一原则在路由层的体现:切换后端不能顺带切换策略。
2.1.296:managed hook 与编码安全
两点:
- managed settings 里的
PreToolUsehook 用"continue": false拒绝、managedprompthook 阻断时,之前会拒绝调用但没有结束回合——Agent 继续往下跑,像是"被拦了一下"而已。现在会真正结束这一轮。 Edit和NotebookEdit在非 UTF-8 文件(Windows-1252、Shift-JIS、GBK)上会替换掉每一个非 ASCII 字符。现在这类编辑直接拒绝。
对你意味着什么:第二条尤其值得抄。数据损坏型 bug 比崩溃更难发现——文件还能打开,只是内容悄悄变了。正确的处理不是"尽力而为地写",而是识别到无法安全处理的编码就停下并报错。
Codex CLI:默认模型换血,能力默认收敛
0.161.0:更强的默认,更窄的自动
- GPT-6.1 Sol 成为默认模型,bundled 目录与 Amazon Bedrock 目录同步。
- Daybreak 改为显式 opt-in:它的控制项和自动 Cyber 路由不再默认出现,除非你主动要求。
- 终端内直接完成 MCP server 登录。
- 每轮可选择 Cyber 访问程序(per-turn access program selection)。
- 记住语音输入/输出设备偏好。
0.162.0 / 0.162.1:工作区与稳定性
- 0.162.0:managed Git worktrees、transcript 复制导航、可配置鼠标滚动。
- 0.162.1:修多行异步提问导致 TUI 崩溃;修后台服务特性不匹配导致的启动失败。
GPT-6.1 Sol Ultrafast 的边界
Ultrafast 模式用更快的 token 生成速度换计划门槛:
- 仅限 Pro $500 与符合条件的 Enterprise / Edu 工作区;
- 企业访问默认关闭,需要 workspace owner 手动开启;
- 推理驻留限制在美国与欧洲(EEA + 瑞士)。
对你意味着什么:
- "默认"是产品表达价值观的地方。把能力最强、控制项最多的模式从默认路径移到 opt-in,等于承认"自动路由"本身需要用户知情同意。你在自己产品里也应该这样处理高风险自动化。
- 治理开关正在变成采购项。企业默认关闭 + 管理员开启 + 数据驻留区域,这三件事决定了它能不能进合规环境。选型时别只看模型分数。
- 0.162.1 这类崩溃修复提醒你:Agent 的 TUI 是长驻进程,异步交互路径(多行输入、后台服务握手)是最容易出稳定性问题的地方。
Cursor Remote Control:手机变成审批端
2026-10-06 上线。要点:
- iOS App 可以查看并给你的电脑上运行的 Agent 发消息;
- Agent 不会搬到云端,仍然跑在本机,手机只是连接端;
- 电脑需要在账户下自动出现,配对需在桌面端批准;
- 电脑必须开机且在线;桌面设置里有 "Keep this computer awake"(需插电、开盖);
- Remote Control 默认开启,Enterprise 组织除外;管理员在
Org settings > Security and identity > Remote control打开; - 不依赖 cloud agents。
对你意味着什么:
- 审批点从"人在电脑前"变成"人在任何地方"。可用性大幅提升,但同时意味着账号就是控制面——手机丢失、会话令牌泄露,等价于有人能对你的本机 Agent 下达指令。
- 企业默认关闭是对的默认值。个人用户至少应该做的:给账户开二次验证,不要在共用设备上保持登录。
- 这类功能真正的价值场景是"Agent 跑到一半卡在权限提示"。它把等待时间从"回到工位"压缩到"掏手机",但也让"随手批准"变得更容易。批准按钮旁边应该显示足够上下文,否则就是在训练用户盲点允许。
Grok Build 1.0.50:两个小改动,两条大原则
grok worktree rm对正在使用或有未保存改动的 worktree,必须显式加-f才能删除;- 长会话不再因为超过 4 MiB 而断连。
对你意味着什么:
- 第一条是"破坏性操作二次确认"的标准实现:不是弹窗问一句,而是要求你在命令里显式表达意图。对 Agent 更友好——它能从错误信息里学到"这里需要人确认"。
- 第二条说明会话长度已经撞上了基础设施的旧假设。4 MiB 这种上限在"一问一答"时代足够,在"跑两小时、几十次工具调用"时代就是故障源。你自建的 Agent 网关、日志管道、WebSocket 层,都该重新算一遍这个账。
五条可复用的护栏原则
把上面的具体修复抽象一层,得到五条能直接抄进自己系统的原则。
原则一:hook 必须 fail-closed
hook 启动失败 / 超时 / 非预期退出 → 阻断(block)
✗ 放行(allow)默认 fail-open 的系统,在依赖缺失、磁盘满、网络抖动时会静默变成"无防护"。Claude Code 2.1.295 的 onFailure: "block" 就是把这条做成显式配置。你自己写 hook 时,第一行就该是"异常路径返回拒绝"。
原则二:默认只读、最小权限
- 新工具默认只读;写权限按目录授予。
- 新插件/新 MCP server 默认不自动信任。
- 新能力(自动路由、Cyber 访问、远程控制)默认关闭,需要显式开启。
Codex 把 Daybreak 改成 opt-in、Cursor 对企业默认关闭 Remote Control,都是这条原则的产品化。
原则三:沙箱边界要按"异常输入"测试
2.1.292 的四个绕过对应四类测试用例,几乎可以直接复用:
| 测试输入 | 期望 |
|---|---|
| Agent 自己产生的临时副本(上传暂存、导出文件) | 仍受沙箱读限制 |
| 会话中途出现/改指向的 deny 路径 | 立即撤销其内部授权 |
| 网络路径(UNC)/符号链接指向的文件 | 与本地路径同等权限提示 |
| 被修改过的策略缓存 | 不得降低策略等级 |
再加两条:非 UTF-8 文件(拒绝编辑而非破坏内容)、读取中途被替换的链接(校验后再返回)。
原则四:worktree 与破坏性操作要二次确认
- 删除 worktree、删分支、
rm -r、覆盖未提交改动 → 必须显式 flag 或交互确认。 - 确认信息要包含"会丢什么",而不是只问"确定吗"。
- Agent 能读到的错误信息里,要写清楚"需要什么才能继续"。
原则五:长会话与可观测性
- 会话/流的上限要按长会话重新评估(Grok 的 4 MiB 就是反例)。
- 每一次被权限拦下、被 hook 阻断、被沙箱拒绝的调用,都要有结构化记录。Claude Code 2.1.296 起为 hook 增加命令、插件、结果、耗时的调试输出,2.1.307 又加了
claude_code.safety_event事件——方向是一致的。 - 没有审计日志的护栏,只是一次性的运气。
团队自检清单
十项,按"能在半天内查完"的粒度设计。检查点可以直接对着配置和日志做,不需要改代码。
| # | 检查点 | 为什么 | 怎么验证 |
|---|---|---|---|
| 1 | 所有安全 hook 都设了 onFailure: "block"(或等价实现) | 失败时默认放行 = 依赖一抖就全线开放 | 故意让 hook 脚本 exit 1 / 超时,观察调用是否被阻断 |
| 2 | deny 规则在每次调用时重新求值,而不是启动时快照 | 中途出现的路径、变化的符号链接是 2.1.292 的绕过点 | 会话进行中修改 deny 配置,再访问该路径 |
| 3 | 沙箱覆盖"自己生成的副本":上传暂存、导出、缓存、凭据文件 | 沙箱内的自有数据最容易漏配 | 在沙箱内 cat 上传暂存目录与配置缓存目录 |
| 4 | 网络路径(UNC、NFS、挂载点)与本地路径走同一套权限判定 | 路径形态分叉是绕过高发区 | 从网络路径读取文件,确认出现同样的权限提示 |
| 5 | 破坏性操作(删 worktree、删分支、rm -r)需要显式 flag 或确认 | 一次误删的成本远高于一次多问 | 在有未提交改动的 worktree 上执行删除,确认被拒 |
| 6 | 安装插件 / 添加 marketplace 与手动操作共用同一套策略检查 | 快捷通道 = 下一个绕过点 | 对比 plugin install --marketplace 与手动 add 的权限行为 |
| 7 | 编码与格式异常时拒绝写入,而不是"尽力转换" | 静默损坏比报错更难发现 | 用 GBK / Shift-JIS 文件触发 Edit,确认被拒而非内容被替换 |
| 8 | 网关/代理的模型白名单在 failover 后仍然生效 | 切换后端不能顺带切换策略 | 模拟主 upstream 故障,检查是否路由到白名单外的模型 |
| 9 | 长会话不因大小上限断开;流式与日志管道已按长会话容量校验 | 4 MiB / 100K 字符这类旧假设会变成静默故障 | 跑一次 1 小时以上、工具调用密集的会话 |
| 10 | 每一次拒绝都有结构化审计记录(谁、什么工具、哪条规则、耗时) | 没日志就无法复盘,也无法证明护栏有效 | 触发一次拒绝,查日志是否包含规则标识与工具参数 |
一周内可以做的三件事
- 升级并读 diff。把
claude --version、Codex CLI 版本对齐到最新,然后只读 changelog 里带sandbox、permission、hook、managed的行。这一周 Claude Code 的安全修复几乎全部集中在这几个关键词下。 - 把 hook 改成 fail-closed。先找那些"用来阻断"的 hook——它们通常已经写了拒绝逻辑,但没处理"自己挂了"的情况。改成异常即阻断,再跑一遍正常流程确认没误伤。
- 写五个绕过用例。直接用上面的表格:临时副本、中途改路径、网络路径、被篡改的缓存、非 UTF-8 文件。写成脚本,进 CI。护栏没有测试,就等于没有。
本节小结
✅ 2026 年 10 月第一周的共同主题是护栏,不是模型能力:Claude Code 安全周、Codex 能力默认收敛、Cursor 远程审批、Grok worktree 保护。
✅ Claude Code 2.1.292 的四个绕过分别对应四类根因:自有数据副本未覆盖、策略只在加载时求值、路径形态分叉、信任本地策略缓存。
✅ 2.1.294 证明自然语言策略不能当 ACL;2.1.295 的 onFailure: "block" 把 fail-closed 变成可配置原语;2.1.296 拒绝会破坏非 UTF-8 文件的编辑。
✅ Codex 把 Daybreak 改为显式 opt-in,Ultrafast 限定 Pro $500 / 企业教育计划、企业默认关闭、推理驻留美欧——"默认"本身就是治理手段。
✅ 五条可复用原则:fail-closed hook、默认只读最小权限、按异常输入测沙箱边界、破坏性操作二次确认、长会话与可观测性。
✅ 护栏要能被验证:十项自检清单 + 五个绕过用例,进 CI 才算落地。
