fix(less-computer): 护栏高危系统命令设为不可批准,修批准注入畸形规则 (#679)#688
Conversation
旧审批流对所有命中 pattern 一律 format!("Bash({p}:*)") 生成 allow 规则:
- 对带空格/参数的子串("sudo " → "Bash(sudo :*)","dd if=" → "Bash(dd if=:*)",
"chmod -r 777 /"、"chown -r")生成的串既不等于 deny "Bash(sudo:*)" 等(故 deny
没被移除、批准静默失效),又把畸形规则注入了 allowed_tools。
改为:新增 guard::deny_rule_for_pattern(pattern),把「可批准」命令(rm -rf / git
push --force / git reset --hard / git clean 等)映射到其在 default_deny_rules 里的
**精确** deny 规则;提权/毁盘/系统级命令(sudo / dd / mkfs / chmod / chown / shutdown
/ reboot / 管道执行 / fork 炸弹)返回 None = 不可批准,即使被批准也保持拦截
(fail-closed),不再注入畸形 allow。审批流用 filter_map 取精确规则,移除的 deny 与
加入的 allow 严格一致。
附单测:每个可批准 pattern 的映射规则确实存在于 default_deny_rules;危险系统命令一律
不可批准。
|
@claude 请审核(安全相关):把无法安全前缀表达 / 提权毁盘系统级命令设为「不可批准」(deny_rule_for_pattern→None,fail-closed),并修掉旧的「批准注入畸形 Bash(sudo :*)、deny 又没移除」不一致。重点看 (1) 可批准集(rm -rf / git push --force / git reset --hard / git clean)是否合适、是否过宽;(2) 不可批准集是否完整覆盖了 HIGH_RISK_PATTERNS 里所有危险项;(3) filter_map 后 allow 与移除的 deny 是否严格一致。 |
|
Claude finished @appergb's task in 3m 16s —— View job 安全审核结果
总结方向正确,核心修复逻辑无误,有一个中等风险设计问题 + 一个测试覆盖缺口。 (1) 可批准集:是否合适?是否过宽?可批准集(7 项): 总体合适,但有一个值得关注的问题:
这两条命令永久删除未跟踪文件。
建议:核实 前缀规则天然宽泛( (2) 不可批准集:是否完整覆盖 HIGH_RISK_PATTERNS 全部 20 项?覆盖完整。
(3) filter_map 后 allow 与移除的 deny 是否严格一致?严格一致,逻辑无漏洞。 关键路径( let allow_rules: Vec<String> = approved_patterns
.iter()
.filter_map(|p| crate::coding_agent::guard::deny_rule_for_pattern(p)) // &'static str
.map(|rule| rule.to_string())
.collect();
if !allow_rules.is_empty() {
deny.retain(|d| !allow_rules.iter().any(|a| a == d)); // 精确字符串匹配
}
// ...
req.allowed_tools.extend(allow_rules); // 同一份字符串三点一致性保障:
其他观察(非 blocker)
结论
|
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR 合并冲突提示1. dictation.rs(与 #682、#692、#666)
2. coding_agent/guard.rs(与 #638)
建议: 若两 PR 都会合,请 rebase #638 时留意 guard.rs 与本 PR 的合并结果。 |
User description
关联 issue
Closes #679
问题
Less Computer 护栏审批流(
coordinator/dictation.rs)对每个命中的HIGH_RISK_PATTERNS子串一律format!("Bash({p}:*)")生成 allow 规则:"sudo "(带空格)→Bash(sudo :*)≠ denyBash(sudo:*)→ deny 未被移除(批准静默失效),同时把畸形规则注入allowed_tools;"dd if="/"chmod -r 777 /"/"chown -r"同理。方案(A:安全优先)
新增
guard::deny_rule_for_pattern(pattern) -> Option<&'static str>:rm -rf/rm -fr/git push --force/git push -f/git reset --hard/git clean -fd/git clean -f -d)→Some(精确 deny 规则),批准时按此从 deny 精确移除、并加入等值 allow(移除的 deny 与加入的 allow 严格一致)。sudo/dd/mkfs/chmod/chown/shutdown/reboot/ 管道执行 / fork 炸弹 / 写块设备)→None:即使被「批准」也保持拦截(fail-closed),不注入任何 allow。审批流改用
filter_map(deny_rule_for_pattern)构造 allow 规则。测试
PR Type
Bug fix, Enhancement
Description
新增
deny_rule_for_pattern函数,区分可批准与不可批准命令修改审批流使用
filter_map,避免畸形allow注入添加单测验证可批准映射与危险命令不可批准
Diagram Walkthrough
File Walkthrough
guard.rs
添加deny_rule_for_pattern及测试openless-all/app-tauri/src-tauri/src/coding_agent/guard.rs
deny_rule_for_pattern函数,将可批准模式映射到精确deny规则,不可批准命令返回Nonedictation.rs
修改审批流使用filter_mapopenless-all/app-tauri/src-tauri/src/coordinator/dictation.rs
allow_rules生成逻辑:使用filter_map和deny_rule_for_pattern替代直接格式化