让 AI Agent 执行 Shell 命令时,开发者通常不愿为每一次 ls 都弹出确认。于是,“看起来只读就放行”的快速路径成为常见设计。但 Dev.to AI 上一篇技术分析指出,在 AgentScope 的 Bash 权限检查中,这类快速路径可能因为对 Shell 分隔符理解不完整而被绕过:一个换行符就可能让后续命令避开检查。
只读快路径为什么会被换行符绕过
按照公开 issue #2470 的描述,AgentScope 的 Bash.check_permissions 会先做注入风险检查,再做只读检查。如果只读分类器判定为“是”,函数直接返回 ALLOW,后续危险模式、危险路径、危险删除路径等层不会再执行。换句话说,快速路径是一条没有人工确认、也缺少后续拦截的代码路径。
这一设计的隐含假设很简单:如果字符串看起来是只读命令,那么 Shell 对这串字符的全部执行行为也应是只读。问题在于,权限检查对“一条命令”的理解,并不总是与 Bash 本身一致。
GitHub issue 中提到,该检查会在命令字符串包含 &&、||、;、| 时进行拆分,并要求每一段都是只读;否则按单条命令处理,并主要根据命令头部判断。但 Bash 的分隔方式不止这四种。例如,单个 & 可以让左侧命令后台执行并继续后续内容;换行符也可以结束当前命令并开启下一条命令。由于这些符号不在列表中,包含它们的字符串会进入单条命令判断路径。只要开头是 ls、cat 等只读命令,后面的内容就可能不被检查。
文章作者对已发布的 2.0.11 版本 wheel 包做了权限检查调用验证,并未实际执行危险命令。测试结果显示,ls; rm -rf /tmp/pwn 会触发 ask,ls && rm -rf /tmp/pwn 也会触发 ask;但 cat file.txt & rm -rf /tmp/pwn、ls -la&rm -rf /tmp/pwn、cat file.txt 加换行后接 rm -rf /tmp/pwn,以及 ls 加 CRLF 后接 rm -rf /tmp/pwn 等组合,得到的是 allow。
不是注入规则没设防,而是语法规则太短
值得注意的是,报告中提到 $(...) 这类命令替换已经在注入风险列表里。因此,像通过命令替换隐藏危险命令的方式会被拦下。但两个普通命令用换行连接时,会在语法树中形成普通命令节点,不会触发注入规则。也就是说,检查器完成了它被写下的逻辑,只是它写下的列表短于 Shell 真实语法。
为了观察“允许”判定是否真的对应执行结果,文章作者构建了一个小型测试网格:7 个只读命令头部,包括 ls、ls -la、cat f.txt、head -n 5 f.txt、pwd、wc -l f.txt、echo hi;10 种分隔符;共 70 个字符串。第二段命令使用无害的 touch 标记命令。每个字符串先记录权限门判定,再用 bash -c 在 GNU bash 5.2.37、Git for Windows 环境中执行,检查标记文件是否出现。
作者也强调,这个无害替代实验能说明:当权限门判定为 allow 时,Bash 会执行前后两部分命令。但它本身不能证明权限门在所有情况下都会允许破坏性命令,因为按命令头部判断的分类器在设计上就会忽略尾部。此前针对包含 rm -rf 字符串但未执行的判定探测,与公开 issue 中的表格一致。
类似问题并非孤例。素材提到,除分隔符相关的 #2470 和 #3473 外,同一软件包还有其他公开报告。用户授权规则也可能有相似形状:有评论者在 #2470 中提到,类似 git status:* 的“始终允许”规则按前缀匹配,而像 npm install 这样的普通规则按子串匹配。文章作者单独测试了 2.0.11 的匹配函数,但未测试完整权限引擎是否会继续询问。其设计问题仍是同一个:规则按“一条命令”编写,却要匹配可能包含多条命令的字符串。
修复思路:少用黑名单,多验证实际执行
从这篇分析看,简单列出危险分隔符并不可靠。Shell 语法比任何黑名单都更复杂,换行、&、命令替换、重定向、引号等都可能改变执行语义。更稳妥的方向是验证系统实际会执行什么,并把权限限制在具体范围内,而不是只在某些位置拦截。
文章作者测试了一个更严格的门控示例:先用正则限制字符集,只允许不能开启新命令、不能展开变量、不能打开重定向的字符;再用命令白名单判断,只允许 ls、cat、head、tail、pwd、wc、echo、grep 等少数命令。任何无法识别的内容都交给人工确认,而不是走快速路径。
在同样的 70 字符串网格上,这个严格门控的结果是 0 allowed。由于网格里每个字符串都包含分隔符,禁止分隔符的门控通过测试并不意外。更现实的比较在成本侧:作者用 16 条普通只读命令测试两种门控,严格版本让 6 条命令进入 ask,包括 git status、git log --oneline -5、cat "my file.txt"、find . -name '*.py'、ls | head -3 和 cat f.txt | wc -l。这些命令中有一部分本可能被希望自动放行,但安全与便利之间的边界需要重新设计。
Agent 权限检查要对齐 Shell 语义
这次换行符绕过事件给 AI Agent 工具链提供了一个具体样本:当模型能够调用 Shell,权限门不再只是产品体验问题,而是执行安全问题。快速路径减少确认次数,提升可用性,但也因此成为缺少人工兜底的入口。
对开发者而言,关键不是记住更多危险符号,而是让权限判断与解释器行为保持一致。命令字符串不是最终动作,Shell 解析、执行顺序、后台任务、替换与重定向都会改变结果。只读判断如果停留在文本前缀和有限分隔符上,就可能把“看起来安全”的命令串交给真实 Shell。
对使用 Agent 执行代码、运维脚本或文件操作的团队来说,这个案例的提醒很直接:任何自动放行规则,都应基于系统实际执行路径来验证;任何“只读”标签,都应先通过完整语法解析和最小权限约束。否则,一个换行符就可能成为安全门后最容易被忽视的入口。
原创文章,作者:点点,如若转载,请注明出处:https://www.dian8dian.com/ai-agent-de-zhi-du-ming-ling-kuai-su-fang-xing-ke-neng-shu