现象
Less Computer(语音 Agent)护栏在用户「批准」sudo / dd / chmod / chown 这几类高风险命令后,命令仍被拦截 —— 用户点了批准却像没生效(静默空操作),同时还会向 allowed_tools 注入一条畸形 allow 规则。
根因(已读源码确认)
coding_agent/guard.rs 维护两份手写、无共享映射的清单,两者格式不一致:
HIGH_RISK_PATTERNS(guard.rs:12-33)的 key 是命中子串,带空格/参数:"sudo "、"dd if="、"chmod -r 777 /"、"chown -r"。
default_deny_rules()(guard.rs:70-110)是前缀说明符:"Bash(sudo:*)"、"Bash(dd:*)"、"Bash(chmod:*)"、"Bash(chown:*)"。
批准流(coordinator/dictation.rs:765-770):
let allow_rules = approved_patterns.iter().map(|p| format!("Bash({p}:*)")).collect();
deny.retain(|d| !allow_rules.iter().any(|a| a == d)); // 仅按“完全相等”移除
于是 "sudo " → Bash(sudo :*)(多一个空格)≠ deny Bash(sudo:*) → deny 没被移除 → 命令仍被拦;同时把畸形规则 Bash(sudo :*) 注进 allow。dd if= / chmod -r 777 / / chown -r 同理。risk_equivalent_patterns 只覆盖 rm / force-push / git-clean,救不了这 4 个。
安全权衡(重要)
这是 fail-closed(批准无效,命令仍被拦)而非放行漏洞。但正确修法需要设计判断:直接让「批准 sudo」去掉 Bash(sudo:*) 会把整类 sudo 放给 agent,风险更大。倾向方案是把无法用安全前缀表达的 pattern(sudo/dd 等)标记为不可批准,或为每个 pattern 建立显式 pattern → deny_rule 映射,让「批准」与「deny 解除」严格一一对应、且不引入畸形 allow。
建议
- 用单一数据表统一
HIGH_RISK_PATTERNS ↔ deny_rule,消除两份清单漂移。
- 决策:这几类是否允许被批准;若允许,批准时按映射精确解除对应 deny,不注入畸形 allow。
- 单测:每个「可批准」pattern 的 deny 规则确实被解除路径匹配;不可批准的 pattern 不产生 allow。
来源:2026-06-16 全仓多 Agent 审计(护栏专项)。需安全设计评审。
现象
Less Computer(语音 Agent)护栏在用户「批准」
sudo/dd/chmod/chown这几类高风险命令后,命令仍被拦截 —— 用户点了批准却像没生效(静默空操作),同时还会向allowed_tools注入一条畸形 allow 规则。根因(已读源码确认)
coding_agent/guard.rs维护两份手写、无共享映射的清单,两者格式不一致:HIGH_RISK_PATTERNS(guard.rs:12-33)的 key 是命中子串,带空格/参数:"sudo "、"dd if="、"chmod -r 777 /"、"chown -r"。default_deny_rules()(guard.rs:70-110)是前缀说明符:"Bash(sudo:*)"、"Bash(dd:*)"、"Bash(chmod:*)"、"Bash(chown:*)"。批准流(
coordinator/dictation.rs:765-770):于是
"sudo "→Bash(sudo :*)(多一个空格)≠ denyBash(sudo:*)→ deny 没被移除 → 命令仍被拦;同时把畸形规则Bash(sudo :*)注进 allow。dd if=/chmod -r 777 //chown -r同理。risk_equivalent_patterns只覆盖 rm / force-push / git-clean,救不了这 4 个。安全权衡(重要)
这是 fail-closed(批准无效,命令仍被拦)而非放行漏洞。但正确修法需要设计判断:直接让「批准 sudo」去掉
Bash(sudo:*)会把整类 sudo 放给 agent,风险更大。倾向方案是把无法用安全前缀表达的 pattern(sudo/dd 等)标记为不可批准,或为每个 pattern 建立显式pattern → deny_rule映射,让「批准」与「deny 解除」严格一一对应、且不引入畸形 allow。建议
HIGH_RISK_PATTERNS ↔ deny_rule,消除两份清单漂移。