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 报告

内置执行决策

扫描结果现在默认包含确定性的 allowaskblock。多条策略同时命中时使用 block > ask > allow,解析错误默认阻止执行。

macOS / Windows 覆盖重点

三语言风险检出矩阵

风险类别Bash 样例Python 样例Node.js 样例结果
下载执行curl … | bashexec(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.d3/3
凭据访问读取 ~/.ssh/id_rsa读取 ~/.ssh/id_rsa读取 ~/.ssh/id_rsa3/3
系统修改写入 /etc/hosts写入 /etc/resolv.conf写入 /etc/resolv.conf3/3
权限提升sudo idos.setuid(0)process.setuid(0)3/3
防御规避删除 audit.log删除 audit.log删除 audit.log3/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.zip3/3

专项用例与结果

行为链

策略放行

跨语言载荷

误报边界

当前结论边界

121 条离线语料得到 precision 100%、recall 99.6%、F1 99.8%,但样本规模仍小, 且不是从生产流量随机抽样,不能外推为真实世界总体准确率。120 条严格匹配; 唯一已知缺口是 Linux journald Storage=none 尚未归类为防御规避。 该 Linux 项按当前 Windows/macOS 优先级暂缓,报告继续如实保留。

真实世界测试与提升路线

  1. 建立隔离语料库:收集经过脱敏和授权的恶意样本,以及安装脚本、 CI 脚本、运维脚本、开发工具等 benign 样本;只存文本,绝不执行。
  2. 逐 finding 标注:每个样本记录语言、期望规则、类别、源码范围、 是否允许额外 finding 和样本来源/许可证。
  3. 分层数据集:训练集用于写规则;验证集用于调参;冻结测试集只用于 发布门禁,防止针对测试样本过拟合。
  4. 量化指标:按规则和类别统计 TP、FP、FN、precision、recall、F1; 同时统计每千行告警数、解析失败率和 P50/P95 扫描耗时。
  5. 变体测试:为每个恶意行为生成引号、变量、别名、换行、管道、 heredoc、包装函数和编码变体;为每个规则加入相似但安全的 hard negative。
  6. 规则提升顺序:先增加 callee/参数结构约束,再做常量传播和简单污点 跟踪,最后处理跨函数与跨语言数据流;每次修复必须同时加入 TP 与 FP 回归样例。
  7. 发布门禁:冻结集不允许已有 TP 退化;critical/high precision 建议至少 95%,整体 recall 目标按业务风险设定;性能超预算则阻断发布。

详细的语料结构、指标公式和迭代流程见仓库中的 真实世界评测方案