一、工具本身的安全性。 它读案例 JSON、起适配器、发 HTTP 请求。它不做的事:不执行案例里写的任意代码、不把适配器的返回体当代码跑、不在判决里用 eval。
二、它能不能被骗。 这条才是重点。agent-web 的核心主张是"适配器可以撒谎,所以判决要能被检验"。能让适配器骗过探针和断言的发现,在这个仓库里是有效漏洞,不是使用问题——那正是它想抓的东西没抓到。
请不要开公开 issue。用 GitHub 的私有漏洞报告:
https://github.com/liuzheng6621/agent-web/security/advisories/new
如果那个入口不可用,发邮件到仓库 owner 的 GitHub 公开邮箱,标题带 [agent-web security]。
48 小时内会收到确认。请给最小复现:一段能让某个判决翻转的代码,比一段描述有用得多。
任何让判决在没有真正验证过的情况下变成 pass 的情况。历史上真发生过三次,都在 docs/museum/ 里留了展品:
- 适配器返回契约外的
outcome(比如'success'),四个分类分支都不命中,这一步滑到终态断言假通过(展品 07); - 同一段分类语义被抄了两份,第二份(录制回放路径)带着同一个洞活了一个版本(展品 08);
- 案例里写了
clock_policy这种没人读的字段,判决pass,但那行从来不代表任何东西(展品 11)。
如果你找到第四种,那是这个仓库最想知道的漏洞。
误报同样有害——它让人去改没坏的东西。尤其是那种只在特定顺序下才出现的误报。
unknown 必须留在分母里。任何把 unknown 变成 pass 或 fail 的路径都是漏洞,包括:
- 环境没起来时仍然报出一个抓获率数字(v0.63.1 修过一次:8181 后端没起,
certify报0.0%并退 0); - 部分案例不可用时,不可用的那部分被算进分子或分母。
probe 查十二项机械性质,crosscheck 用独立通道复核响应。已知抓不到的两类,这两类不算新发现(docs/LIMITS.md L8 已写明):
- 会看探测器的骗子:先探测环境、确认在测试里,再表现正常;
- 把整个
globalThis.fetch换掉,连crosscheck的独立通道一起接管。
除此之外的绕过路径都算。特别是:适配器在 reset() 里留下状态,让第二次运行看到不同的东西——这类"只在重复运行下才露馅"的作弊最难查,也最有价值。
- 真实后端域的适配器连不上服务(那是环境问题,
certify会退 2 说"这一跑不成立"); - 案例本身写错了(那是案例的 bug,不是工具的安全问题);
- 在
cases/里放一个恶意构造的 JSON 让工具崩掉——工具崩掉可以接受(它会退非 0),静默判pass不可接受。这个区别很重要:宁可崩,不要撒谎。
只有最新 tag(当前 v0.64.0)接受安全修复。这是个人项目,不维护旧版本分支。
它不是安全边界。适配器在同一个进程里跑,probe 是"检查它诚不诚实",不是"阻止它做坏事"。要跑不可信的适配器,请自己套容器或进程隔离——docs/LIMITS.md L8 把这条写成了明确的边界,不是遗漏。