agent-tool-scanner 测试报告
Tree-sitter Bash、Python、Node.js 静态风险检测
172 / 172
单元测试通过
3 / 3
测试文件通过
120 / 121
语料完全匹配
99.6%
语料类别召回率
20 / 20
决策标注匹配
33 / 1455
Atomic 目标 GUID 入库
执行结论
通过:Bash、Python 和 Node.js 均能在精选样例中检出全部 12 类风险。
额外测试覆盖行为链、可信下载域名、私网 IP、源码位置、语法错误、 Bash 内嵌 Python/Node.js、静态管道、heredoc、扫描限制和已知误报边界。
报告基线:3 个测试文件、172 个测试。详细断言和耗时见 Vitest HTML 报告。
内置执行决策
扫描结果现在默认包含确定性的 allow、ask 或
block。多条策略同时命中时使用
block > ask > allow,解析错误默认阻止执行。
policy.locale: "zh-CN":返回中文标题和原因(默认)。policy.locale: "en":返回英文标题和原因。- 稳定的英文
policyId不随语言变化,可以用于动作覆盖和审计。 ai-agent默认严格执行;audit将阻止降为人工确认。- 20 条跨语言决策基线中 False Block、多余确认和危险放行均为 0。
macOS / Windows 覆盖重点
- macOS:公开样本覆盖 Keychain、Safari Cookie、Chrome Login Data、 LaunchAgent、emond 和 Time Machine;本轮新增 Chrome 凭据数据库复制暂存。
- 新增真实样本的两条
cp ~/Library/"Application Support/Google/Chrome/…/Login Data"均命中credential.chrome-login-data-stage。 - Windows:当前覆盖 Bash 中调用
powershell/pwsh, 尚无原生 PowerShell AST,不能视为完整的.ps1检测。
三语言风险检出矩阵
| 风险类别 | Bash 样例 | Python 样例 | Node.js 样例 | 结果 |
|---|---|---|---|---|
| 下载执行 | curl … | bash | exec(requests.get(...).text) | eval(await fetch(...).text()) | 3/3 |
| 动态执行 | eval "$payload" | eval(payload) | eval(payload) | 3/3 |
| 持久化 | crontab /tmp/jobs | 写入 /etc/cron.d | 写入 /etc/cron.d | 3/3 |
| 凭据访问 | 读取 ~/.ssh/id_rsa | 读取 ~/.ssh/id_rsa | 读取 ~/.ssh/id_rsa | 3/3 |
| 系统修改 | 写入 /etc/hosts | 写入 /etc/resolv.conf | 写入 /etc/resolv.conf | 3/3 |
| 权限提升 | sudo id | os.setuid(0) | process.setuid(0) | 3/3 |
| 防御规避 | 删除 audit.log | 删除 audit.log | 删除 audit.log | 3/3 |
| 网络外联 | curl https://… | requests.get(...) | fetch(...) | 3/3 |
| 数据外传 | curl -T file … | requests.post(...) | fetch(... POST ...) | 3/3 |
| 破坏行为 | rm -rf / | shutil.rmtree(...) | fs.rmSync(... recursive) | 3/3 |
| 解释器逃逸 | python -c "$payload" | subprocess.run(['bash',…]) | child_process.spawn('bash',…) | 3/3 |
| 二阶段载荷 | 下载→解压→运行 | 下载 payload.zip | 下载 payload.zip | 3/3 |
专项用例与结果
行为链
curl URL | bash:仅产生一条下载执行链,并保留网络外联。- 下载压缩包→解压→运行安装脚本:检出二阶段载荷。
- 读取本地文件→上传:检出数据外传行为链。
策略放行
- 精确可信域名和
*.corp.example子域名规则按预期放行。 - 相似恶意域名不匹配;动态 URL 默认 fail-closed。
- 私网 IPv4 可显式放行;网络外联告警仍独立保留。
跨语言载荷
python -c、node -e、heredoc 和静态管道均进入对应 AST 扫描。- 外层
range、内层innerRange和origin得到验证。 - 动态变量载荷不猜测解析;长度和嵌套限制生效。
误报边界
- 注释以及普通字符串里的危险命令不会作为实际调用检出。
- 普通 Python subprocess 不误报为提权。
- 普通 Node.js GET 不误报为数据外传。
当前结论边界
121 条离线语料得到 precision 100%、recall 99.6%、F1 99.8%,但样本规模仍小,
且不是从生产流量随机抽样,不能外推为真实世界总体准确率。120 条严格匹配;
唯一已知缺口是 Linux journald Storage=none 尚未归类为防御规避。
该 Linux 项按当前 Windows/macOS 优先级暂缓,报告继续如实保留。
真实世界测试与提升路线
- 建立隔离语料库:收集经过脱敏和授权的恶意样本,以及安装脚本、 CI 脚本、运维脚本、开发工具等 benign 样本;只存文本,绝不执行。
- 逐 finding 标注:每个样本记录语言、期望规则、类别、源码范围、 是否允许额外 finding 和样本来源/许可证。
- 分层数据集:训练集用于写规则;验证集用于调参;冻结测试集只用于 发布门禁,防止针对测试样本过拟合。
- 量化指标:按规则和类别统计 TP、FP、FN、precision、recall、F1; 同时统计每千行告警数、解析失败率和 P50/P95 扫描耗时。
- 变体测试:为每个恶意行为生成引号、变量、别名、换行、管道、 heredoc、包装函数和编码变体;为每个规则加入相似但安全的 hard negative。
- 规则提升顺序:先增加 callee/参数结构约束,再做常量传播和简单污点 跟踪,最后处理跨函数与跨语言数据流;每次修复必须同时加入 TP 与 FP 回归样例。
- 发布门禁:冻结集不允许已有 TP 退化;critical/high precision 建议至少 95%,整体 recall 目标按业务风险设定;性能超预算则阻断发布。
详细的语料结构、指标公式和迭代流程见仓库中的 真实世界评测方案。