Rust Agent 子进程执行:Command 之前,先定义输入和超时

Rust Agent 子进程执行:Command 之前,先定义输入和超时

一、让 Agent 执行命令是高风险能力

系统级 Agent 工具常需要调用本地命令,比如读取 Git 状态、运行测试、格式化代码。Rust 的 std::process::Command 很方便,但让模型间接执行命令,风险很高。输入、路径、环境变量和超时都必须受控。

命令执行设计的第一原则,是只允许明确授权的动作。不要把模型输出的字符串直接丢给 shell。能不用 shell 就不用 shell,参数分开传,路径先规范化。

上个月我在测试 Agent 的自动修复能力时,差点出了事故。Agent 知道可以运行 rm 命令,模型在一次对话中尝试了 rm -rf /tmp/xxx。虽然 /tmp 不是核心数据,但让我出了一身冷汗。如果一个 Agent 能执行任意命令,而开发者没有设白名单,那它就是提权工具。从那一刻起,我把命令白名单放到了系统设计的最高优先级。

二、执行链路要有安全闸

flowchart TD A[模型请求执行] --> B[命令白名单] B --> C[参数校验] C --> D[工作目录限制] D --> E[超时控制] E --> F[执行并捕获输出]

白名单决定能执行什么,参数校验决定怎么执行,目录限制决定在哪执行,超时控制决定最多等多久。四层少一层,风险都会上升。

输出也要限制。某些命令会输出大量日志,直接塞回模型上下文会浪费 token,甚至泄露敏感信息。执行器应截断输出,并保留完整日志路径供人工查看。

三、Rust 代码要避免 shell 注入

rust 复制代码
use std::process::Command;
use std::time::Duration;

fn run_git_status(repo: &str) -> std::io::Result<String> {
    let output = Command::new("git")
        .arg("-C")
        .arg(repo)
        .arg("status")
        .arg("--short")
        .output()?;
    Ok(String::from_utf8_lossy(&output.stdout).to_string())
}

这里没有把整段命令拼成字符串,也没有调用 shell。参数逐个传入,能减少注入风险。真实项目还要校验 repo 是否在允许目录内。

rust 复制代码
fn is_allowed_command(cmd: &str) -> bool {
    matches!(cmd, "git_status" | "cargo_test" | "fmt_check")
}

白名单应使用业务动作名,而不是原始命令字符串。这样模型申请的是"查看状态",执行器决定具体命令。

生产环境实战经验

白名单用业务动作名还有一个好处:参数可以校验。git_status 动作传给你的参数只有 repo,你可以在执行器里做路径安全校验。但如果是 run_shell: { cmd: "git status" },你就很难约束参数了。有一次我偷懒用了后一种方式,模型在一次测试中传了 cmd: "git push --force",虽然是测试环境没出问题,但暴露了安全漏洞。业务动作名虽然写起来多一点,但安全边界清楚很多。

四、超时和取消不能缺席

标准库的 Command 没有直接 timeout,需要结合子进程管理或使用 async runtime。长时间运行的测试、卡住的脚本、等待输入的命令,都可能让 Agent 挂死。

执行器还要处理退出码。非 0 不一定是系统错误,测试失败、格式检查失败都是可理解结果。要把退出码、stdout、stderr 和截断状态结构化返回。

环境变量也要收紧。默认继承父进程环境很方便,但可能把密钥传给子进程。执行命令时可以构造最小环境,只传 PATH 或必要变量。涉及 AI 工具时,API Key 更不能无脑透传给任意命令。

工作目录要做 canonicalize,并确认仍在允许根目录内。简单字符串前缀判断可能被 ..、软链接和大小写差异绕过。路径安全是系统级 Agent 的底线。

一个路径越界的真实案例

我见过一个 Agent 工具用字符串前缀做路径检查。用户传入 path=/workspace/../../../etc/passwd,前缀判断通过了,因为 ../../.. 被当成了路径的一部分。工具最终读取了 /etc/passwd。后来改成 canonicalize 之后再检查前缀,才堵上这个漏洞。软链接也可能绕过检查,所以 canonicalize 不是可选的,是必须的。

还要处理 stdin。很多命令等待输入会卡住,执行器应默认关闭 stdin,除非命令能力明确需要交互。Agent 工具更适合非交互命令,交互式任务应转成明确参数。

最后,审计日志要记录动作名、参数摘要、工作目录、退出码和耗时。命令执行出了问题,必须能回放当时发生了什么。

五、总结

Rust Agent 子进程执行要有命令白名单、参数校验、工作目录限制、超时和输出截断。不要把模型字符串直接交给 shell。

Command 很强,也很危险。让 Agent 会执行命令之前,先让执行器会拒绝命令。

相关推荐
happylifetree2 小时前
Python70:核心语法-函数进阶-案例2
python
王中阳Go3 小时前
两个入口答案不一致先别调模型:6 行入口口径对账表(附脚本)
人工智能·后端·python·大语言模型·1024程序员节
BK贝壳3 小时前
bool-hybrid-array 落盘我只认 .bha:用 Create_BHA / Ask_BHA 做布尔数组序列化
数据结构·python·numpy·1024程序员节
Sakura_j_h_4 小时前
Python 在定时任务里输出 emoji,UnicodeEncodeError 从哪来
开发语言·字符编码·windows·python·定时任务
supabc1235 小时前
欧盟电子发票(XRechnung/Peppol/ZUGFeRD)踩坑记:用 Python 不装 Java 跑官方校验规则
xml·python·开源·电子发票·1024程序员节
ZhengEnCi5 小时前
AI Agent工具调用防护层怎么写-一份能直接跑的Python四层拦截实现
python·llm·agent
ZhengEnCi6 小时前
AI Agent工具误调用怎么解决-从参数校验到高危二次确认的四层工程防线
python·llm·agent
镜子AI7 小时前
镜子AI工程教程:用Python实现关键词布局检查器与语义改写查重(附完整代码)
人工智能·python·microsoft
小oo呆8 小时前
【学习心得】Python协程
python
信誓旦旦的程序猿8 小时前
【Python量化实战宝典 #22】涨跌停、连板情绪手册:情绪指标构建(Python 可跑)
python·1024程序员节·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口