fix(security): P0 安全修复——cron/hooks 门控、WS 握手超时、seed 工具审批、tunnel IP 过滤 - #511
fix(security): P0 安全修复——cron/hooks 门控、WS 握手超时、seed 工具审批、tunnel IP 过滤#511zayokami wants to merge 3 commits into
Conversation
安全审计(并行 8 维度 + 对抗性验证)确认的 4 条高危链路,全部带复现测试修复: 1. 远程 cron/hooks 任意命令执行(confirmed×2):CronManage 直通臂此前无任何 功能开关门控(terminal/git/tunnels 均有)。新增 enable_web_automation 后端 强制开关:网关 guard.go 门控 + 桌面端 envelope_handler 镜像检查(403), 设置未同步时 fail-closed。另修复 run_now 绕过 enabled 检查的缺陷。 - 测试:v2_cron_gating_test.go(修复前:开关关闭仍放行转发) 2. WS 预认证静默连接槽位耗尽 DoS(confirmed×2):/ws/v2/agent 与 /ws/v2/terminal 升级后无任何读超时,无凭据连接可永久占用槽位。 升级后立即设置握手窗口(IdleTimeout,与浏览器链路同公式), 认证完成后清除(存活由既有心跳机制维持,不误杀健康连接)。 - 测试:v2_handshake_deadline_test.go(修复前:静默连接永不关闭) 3. <seed:tool_call> 恢复路径绕过工具审批门(confirmed×2):提示注入可诱导 模型输出标记文本,恢复执行绕过 resolveToolGate(ask/deny 策略)。 恢复循环现在与结构化调用同权过门,拒绝时 reason 作为 toolResult 返回。 - 测试:agent-runner.test.mjs gate 用例(修复前:工具直接执行) 4. Tunnel 目标允许云元数据/保留段 SSRF(plausible×2):validate_tunnel_target_url 只拒绝非 IP 主机名,169.254.169.254/保留段全放行。新增与网关 Go 侧对齐的 IP 黑名单(link-local/元数据/多播/保留/广播),localhost、回环与 RFC1918/ULA 保持放行(暴露本地服务是 tunnel 本职);数据面 proxy.rs 复用同一校验。 - 测试:validate_tunnel_target_url 拒绝用例(修复前:169.254.169.254 通过) 回归:Go/Rust/前端测试在改动域全部通过;剩余失败均为基线环境问题 (Windows 权限位、shell/git 行为、web/dist 缺失),与本次改动无关。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
PR governance checks passed. Awaiting human review. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
审核结论:当前不建议直接合入本次审核基于精确头提交 1. 阻断·安全:seed 审批门仍晚于可执行 Hook 事件
该回调会在 因此,提示注入产生的 seed 工具调用即使随后被用户拒绝,Hook 副作用也已经进入执行队列,仍存在审批前副作用链。拒绝分支还直接 建议:把 seed 2. 阻断·安全:Tunnel 元数据过滤可被 IPv4-mapped IPv6 绕过
对抗验证: 也就是说,目标仍可映射到云元数据地址。仓库 Go 侧已有正确先例: 建议:统一规范化映射地址后再应用 IPv4 黑名单,并新增 3. 阻断·功能合同:
|
…开关全链路、恢复本地 Run Now 语义 针对 PR Stack-Cairn#511 审核的 4 个阻断问题的修订: 1. seed 审批门先于可执行事件:resolveToolGate 移到 onToolCall/onToolExecutionStart 之前(后者会派发 tool_execution_start,Hook 据此立即执行 Bash/HTTP);拒绝时 补齐 onToolResult(toolResultReceived 配对,不留下运行中状态)。回归测试断言 拒绝路径不触发 onToolExecutionStart、且拒绝原因经 onToolResult 到达 transcript (旧顺序下该测试失败=复现)。 2. tunnel 目标过滤 unmap:is_blocked_tunnel_target_ip 的 IPv6 分支先 to_ipv4_mapped() 还原再走 IPv4 黑名单(对齐网关 Go 侧 outbound_http.go 的 Unmap() 先例),http://[::ffff:169.254.169.254]/ 不再绕过元数据段拦截。 创建路径与数据面共用同一校验,新增 mapped 拒绝/放行用例(禁用检查时测试 失败=复现)。 3. enableWebAutomation 全链路:补齐共享 types.ts、normalizeRemoteSettings、 默认值、mergeSyncedRemoteSettings、buildGatewaySettingsSyncPayload、桌面 RemoteSection 开关(Zap 图标)、zh/en 标题与双端 Hint(i18n 校验要求两 host 同时提供)。新增 TS round-trip 测试(归一化→同步载荷→应用→再归一化, 缺字段载荷不覆盖 true)+ Rust 持久化重载断言 + WebUI 同步载荷断言。 4. 恢复本地 Run Now 语义:scheduler.run_now 撤销 enabled 拒绝(enabled 只控制 定时调度,UI 的 Run Now 按钮不因 enabled=false 禁用);远程限制移到 gateway_bridge::handle_cron_manage 的 run_now 边界(ensure_remote_run_now_allowed), 禁用任务不可经 WebUI 远程触发。删除与语义冲突的旧测试,新增远程策略测试 (拒绝/放行 + 本地 store 仍可加载禁用任务为手动上下文)。 回归:Rust 域 112/112;GUI 前端 1850/1855(5 个为既有 Windows 基线失败, 干净树同样失败);WebUI 578/578;i18n 共享键 5/5;diff --check 干净。 UI 边界检查的 3 条告警在干净基线同样存在(Windows 环境预存)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
已按审核意见修订 4 个阻断问题,新 SHA 已推送(f5c6759)。
回归:Rust 域 112/112;GUI 前端 1850/1855(5 个失败为 Windows 基线预存,干净树同样失败);WebUI 578/578;i18n 共享键校验 5/5;git diff --check 干净。UI 边界检查的 3 条告警在干净基线同样存在(Windows 环境预存)。 |
背景
并行安全审计(8 维度挖掘 + 12 条高危对抗性验证 + 人工复核)确认的 4 条高危链路(issue #512)。每条修复都带复现测试:先在未修复代码上证明漏洞存在(测试失败),修复后转绿。
Closes #512
Screenshots / preview
本次改动为运行时逻辑(工具审批门、协议门控),无 UI 视觉变化;以下是四项修复的复现测试证据(before/after):
修复内容
1. 远程 cron/hooks 任意命令执行(confirmed×2,最严重)
CronManage无任何功能开关门控(terminal/git/tunnels/SFTP 均有),持网关 token 者可提交并立即执行任意 bash 脚本;本地也无任何设置可禁用enable_web_automation后端强制开关guard.go:CronManage 移入门控分支,fail-closedenvelope_handler.rs:镜像检查(403 纵深防御)run_now绕过enabled检查的缺陷v2_cron_gating_test.go(修复前:开关关闭仍放行转发)2. WS 预认证静默连接槽位耗尽 DoS(confirmed×2)
/ws/v2/agent与/ws/v2/terminal升级后无读超时,257 条裸连接即可打满全部槽位IdleTimeout,与浏览器链路同公式);认证完成后清除,由既有心跳维持存活,不误杀健康连接v2_handshake_deadline_test.go(修复前:静默连接永不关闭;另含认证后空闲连接存活回归测试)3.
<seed:tool_call>恢复路径绕过工具审批门(confirmed×2)resolveToolGate(ask 审批卡片/deny 策略全部失效)agent-runner.test.mjs两个 gate 用例(修复前:工具直接执行)4. Tunnel 目标允许云元数据/保留段 SSRF(plausible×2)
validate_tunnel_target_url只拒绝非 IP 主机名,169.254.169.254云元数据/保留段全放行proxy.rs复用同一校验validate_tunnel_target_url拒绝用例(修复前:169.254.169.254通过)回归
git diff --check/ gofmt / biome行为变更说明
新增 Remote 设置
enable_web_automation(默认关闭,fail-closed):开启后远程 WebUI 才能管理 cron/hooks。WebUI 的设置 UI 可在后续 PR 中补充开关入口。🤖 Generated with Claude Code