TrueForge 团队在黑客松中构建了 Falcon:一个在隔离沙箱中针对 PR 引入的攻击面运行真实漏洞利用的 Agent,用另一模型族独立审计后写入防篡改账本,误报率为零。
一场来自 TrueForge Agent Harness Hackathon 的田野报告。
mysticalseeker24 / falcon-harness
Falcon 是一个基于 TrueForge 构建的差分范围利用代理(diff-scoped exploitation agent)。它读取一个 Pull Request,计算出该变更引入的新攻击面,在隔离沙箱中启动应用,针对那个特定攻击面运行真实漏洞利用,然后返回请求、响应和裁决——一个经过验证的事实,而非 Severity 评分猜测。在结果被密封到防篡改的哈希链账本之前,另一个模型族会独立审核这个结论。如果变更干净且人类批准,Falcon 就合并它;如果存在可利用漏洞,Falcon 阻断合并并附上证明。
结果:1 个植入缺陷被捕获,0 次误报,1 个健康对照——各跑 3 轮,所有裁决均正确。复现方式:cd attesta-mcp && npm run bench(它启动真实 Fixture,探测它,用不同模型族审核,密封 + 验证,遇到任何错误裁决则非零退出)。
专为 TrueForge Agent 构建……
我用过的每一个安全扫描器都在告诉我同样令人不满的事情:"这里可能有问题,Severity:中。"可能。AI 编码代理让这变得更糟——它们快速上线新端点,时不时有一个忘记加 Auth 校验,然后扫描器耸耸肩给它打个数字。
所以这次黑客松我构建了一个扫描器的反面。它叫 Falcon,它不猜测。它读取 Pull Request,计算变更引入的新攻击面,在隔离沙箱中启动应用,针对那个攻击面运行真实漏洞利用。它返回三样东西:请求、响应和裁决。不是 Severity 评分——而是捕获到的事实。
在我们的故意留有漏洞的 Fixture 上,效果是这样的。一个 PR 添加了 GET /admin/balances 但遗漏了 Auth 中间件。Falcon 发送一个未认证请求,收到了 200 OK 以及所有租户的账户余额。裁决:已利用(EXPLOITED)——它阻断合并,并附上精确的请求和响应作为证明。改一行让路由加上保护,同样的探测得到 401,然后 403,然后管理员拿到 200——裁决:干净(CLEAN),Falcon 提出合并建议并停下来等待人类批准。
那条改变了所有的设计规则
黑客松的整个前提是一个测试框架——TrueForge——它运行 Agent 循环、分发工具、配置沙箱,并暂停等待人类批准。核心评判标准是:框架是否真的在干活,而不是被一个薄薄的 App 包裹着。
这变成了我一段时间以来最有用的设计约束:不要构建循环。每当我发现自己想要一个编排器、重试状态机、步骤序列器时——停下,那是 TrueForge 的工作。留给我编写的部分少得惊人,而且异常干净:
一个 MCP 服务器(三个工具:确定差分范围、密封证据、验证账本),
一个 SKILL 文件——Agent 遵循的操作手册,
一个 vulnbank 目标 Fixture,
以及一个渲染证明的仪表板。
TrueForge 做其余的事情。克制住构建更多的冲动反而让架构变得更好,而不是更差。这是我从中吸取的教训:当你有一个好的框架时,做减法本身就是设计。
任何构建的有趣之处在于它会反击。
框架在我机器上跑第一步就崩了。TrueForge 在原生 Windows 上第一次运行时就抛出了 ESM 路径错误。困惑了一个小时后:它不喜欢 C:\ 风格的路径。我把整个东西移入 WSL2,它就活过来了。(我把 bug 写成上游 issue——把它传递下去。)
一条错误的路径毁掉了整个沙箱。用稍微偏差的路径导入 Skill 不仅仅导致 Skill 失败——它让沙箱中的每条命令都报错。故障是全局性的,错误信息是隐晦的。修复:Skill 路径是目录,不是文件。小陷阱,巨大冲击半径。它现在是我的设置文档第一条警告。
审核者可以给自己橡皮图章。Falcon 在任何人看到结果之前,会用来自不同家族的第二个模型审核每个发现。我第一个版本让主 Agent 传递一个 auditor_ok: true 标志——而这个主 Agent 当然可以……总是设为 true。一位 Reviewer 抓到了它。修复方案是把审核移到密封步骤内部,在服务器端执行,调用方无法伪造结果;并强制审核者必须是真正不同的模型族(我在运行时比较 Provider 前缀)。"书写者永远不是自己的验证者"成为一个承重原则。
一个判断优美但不肯写一行代码的模型。我用了一个便宜的 GLM 模型作为审核者,它判断证据很出色。然后我让它生成一个修复代码片段,它返回了……空内容。每次都这样。事实证明它在"以严格 JSON 格式回复"的代码提示下会闭嘴。与其对抗它,不如把代码建议工具指向另一个能干净输出的模型,并让解析器更具容错性。不同的工作,不同的模型。
Reviewer 抓到了我的修复遗漏的 Bug。这个我莫名骄傲。Qodo 审核了我的部署 PR 并标记出:往账本里写种子数据不是事务性的。我修复了。Qodo 再次审核并再次标记:我的修复仍然在复制它指向的证据制品之前就先写了账本文件——所以如果在复制过程中崩溃,会留下一个看起来已初始化但实际已损坏的链,之后每次启动都会接受它。真正的修复:先复制制品,最后用原子重命名提交账本标记,并添加恢复路径。这才是一个真正发挥作用的审核循环。
可度量,而非断言
在某个中间阶段,我在 README 里写了"N 个缺陷被捕获,0 次误报"作为占位符——然后给自己定了一条规则:没有可运行的东西产出数字就不能发出去。所以 bench 启动真实 Fixture,每个分支跑三遍真实流水线,从实际 HTTP 响应推导出每个裁决,遇到任何错误裁决就非零退出。README 里的标题就是上次运行打印的内容。一个失败的 bench 就是一次构建损坏。如果你声称了一个数字,就用命令来支撑它。
它真的有效吗?
是的,端到端,真实运行。指向真实 PR,Falcon 配置了 Daytona 沙箱,克隆了精确的 Commit,安装了 Node,启动应用:面对有漏洞的 PR,捕获了未认证的 200 + 跨租户余额 → 已利用,密封到哈希链账本。面对安全的 PR,401/403/200 → 干净,建议合并,并暂停等待我批准。账本通过重新读取字节来重新验证;篡改一行,验证立即捕获。
我会告诉下一个构建者的三件事
第一,让框架干活——这周我写的最好的代码是没写的那部分代码。第二,让你的声明可证明——捕获到的漏洞利用胜过 Severity 评分,可运行的基准测试胜过一句话。第三,保持批评者独立——如果检查工作的东西和做工作的东西是同一个,那你就根本没有检查。
Falcon 是差分范围利用代理,基于 TrueForge 构建,每一步都由 Qodo 审核。证明,而非猜测。
在我的指导和审核下用 AI 编码助手构建——巧合的是,Falcon 之所以存在正是因为 AI 写出的代码看起来干净,但实际上可能比它读起来风险大得多。
