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 环境预存)。 |
|
This PR has been inactive for 14 days and is marked stale. It will be closed in 14 days if there is no further activity. Push an update or comment to keep it open. |
背景
并行安全审计(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