## 文件与行号 - internal/tool/command_gate.go:210-219(ASK 层五条裸符号注入规则) - internal/tool/run_command.go:840-850(bypass 降级放行 + Record("gate","ask-allowed")) - internal/tool/security_ledger.go:38(阈值 3)、:113("was denied N times" 横幅文案) - internal/tool/command_gate_test.go:136-161(把误报钉死为期望行为) ## 问题描述(独立复核确认,A-E 全部成立) gate 的 40+ 条规则全部按**命令内容**定级(rm、sudo、curl|sh、DROP TABLE…),唯独注入段五条规则按 **shell 语法原语**判定: - `\$\(`、`` `.+` ``:bash 命令替换是普通组合语法,`$(date)` 无害 - `\$\{`(218 行):desc "parameter expansion \${} can execute code" 在 bash 语义上错误——`${var}` 是纯参数展开,不执行命令;能执行代码的是 eval+展开组合,而规则表没有 eval 规则 - 五条规则均未设 quotedInert:`echo '${PATH}'` 纯引号文本也触发 Ask - PowerShell 会话更严重:`${tk}`、`$(...)` 是 PS 日常变量/子表达式语法,gate 无 shell 区分,全量命中 冗余性:`$(curl x|sh)`→249 行、`$(rm -rf x)`→223/225 行、`$(sudo x)`→243 行均已独立覆盖——裸规则对"嵌套已知危险命令"零增量;唯一增量是嵌套 gate 本就不认识的命令,与 gate 内容判定哲学自相矛盾。 ## 触发场景(用户实测截图 + 机制推演) 1. PowerShell 会话 `git push "https://oauth2:${tk}@..."` → 命中 `\$\{` → Ask → bypass 降级放行(命令实际执行成功)→ run_command.go:847 记为 denial → 同会话累计 186 次 → 每条后续命令前缀注入 "SECURITY ESCALATION: ... was denied 186 times ... stop varying the command" 的**事实性错误指控** 2. bash 正常构建:`go build -ldflags "-X main.v=${V}"` 非 bypass 模式直接被 Ask 打断 ## 预期 vs 实际 - 预期:注入检测针对"替换体内嵌危险内容"(远程取回执行、解码到 shell);纯变量插值/命令替换放行 - 实际:语法原语即 Ask;bypass 下高频虚假 escalation 注入 agent 上下文(狼来了效应稀释真实探测信号) ## 残余缺口(删裸规则需补偿) `base64 -d x | sh`、`echo $(printf 'xxx' | base64 -d) | sh` 目前不被任何规则命中(249 行要求 curl/wget 前缀)——这是裸 `$(` 唯一真实价值的捕获面。 ## 修复建议 1. 规则层:删除/收窄五条裸符号规则;新增"解码到 shell":`(?i)(base64|openssl\s+enc\s+-d|xxd\s+-r\s+-p)\b.*\|\s*(ba)?sh\b`(结尾 \b 吸取 #815 教训) 2. ledger 语义层(独立修,优先级更高):Record 增加 outcome 区分 blocked 与 downgraded-allow;ask-allowed 不应触发 "was denied N times" 文案(或改为 "auto-allowed N times");阈值 3 对该路径过敏感 3. 测试层:改写 TestCommandGate_InjectionPatternsAskNotBlock——`echo $(whoami)`、`echo ${PATH}`、`cat <(echo hello)` 改期望 Allow,新增 base64|sh 期望 Ask ## 严重程度 High(独立复核实评:无安全绕过/数据破坏,fail-safe 方向;但高频虚假 SECURITY ESCALATION 污染上下文 + 非 bypass 模式可用性损伤显著)
Activity
topcheer commentedon Oct 17, 2026
修复进展:PR #4274(draft)已开出,覆盖本 issue 的 ledger 语义层(ask-allowed 分组+中性文案+阈值10)与解码规则补偿(base64/openssl/xxd 解码到 shell → Ask)。规则表降级(五条裸符号规则→warning)由 #4238 承担,两者互补、已与 @ggcxf_reviewer 对齐叠加终态与验收清单。测试:zz_issue4273_test.go 5 组钉死 + zz_issue3282_test.go 适配,全包 go test 绿。
topcheer commentedon Oct 17, 2026
又一个活体实证(用户 mac mini TUI,8ef147bf5 版本,bypass 模式):k8s 常规运维链(kubectl exec mysql pod 写 app_settings/dep_upgrades)被弹 'Bypass mode approval'。根因:命令含 MySQL 标识符反引号 `key`(app_settings(`key`,value,...)),裸反引号规则 `.+` 误判为 shell 命令替换。实测复现:gate.Check → ask=true 'backtick command substitution';permission 层对 Bash 工具本来就 allow(#4290)。PR #4291 分支同命令实测 allow(behavior=0)——该 PR 精确覆盖此场景,合入发版后消失。
fix(tool): #4273 command gate asks on shell syntax primitives, not da…
fix(permission): quoted-body redirect gate only fires for interpreter…