两天找到 100+ 个 Critical 漏洞、已经拿到 12 个 CVE:Google/Mandiant 这套多 Agent 代码审计真正值得抄的是“怀疑链”
昨天 Google Threat Intelligence Group 公开了一套内部使用了 10 个月的系统:Agentic Vulnerability Discovery Harness,AVDH。
公开数据很扎眼:
一次涉及被盗企业代码仓库的事件响应中:
2 天发现 100+ 个真正的 Critical 漏洞
过去 10 个月里,这套 Harness 已经:
分析数千万行代码
执行数千条 Pipeline
产生数万条 Finding
目前公开材料里提到,相关工作已经推动了 12 个 CVE 的分配,还有十多个问题处于披露流程中。
这些数字足够做标题。
但我看架构时最想抄的不是“多 Agent”,而是另一件事:
他们没有让一个模型从头到尾相信自己,而是专门设计了怀疑、验证和证据升级流程。
这比“再加一个 Reviewer Agent”具体得多。
传统 SAST 为什么和 LLM 审计不是同一种东西
传统规则扫描很擅长:
危险函数
已知模式
不安全 API
依赖漏洞
但代码漏洞经常需要理解:
这个入口普通用户能不能访问?
这段代码实际上会不会被执行?
这个参数经过哪些校验?
管理员路径和普通路径是不是共享了状态?
Google 文章里就特别提到,LLM 的优势之一是能区分:
普通用户可访问代码
管理员限制代码
根本不会执行的代码
这属于语义和控制流理解。
但“模型觉得这里有漏洞”远远不够
如果一个 Agent 扫 1000 万行代码,然后输出:
发现 80,000 个潜在漏洞
安全团队基本没法用。
真正重要的是:
True Positive Density
也就是:
人真正值得看的发现比例
AVDH 的设计重点之一,就是把模型生成的候选发现继续送进结构化验证,而不是把第一轮猜测直接变成工单。
我会把代码安全 Agent 拆成五个角色
Scout
→ Analyst
→ Skeptic
→ Validator
→ Reporter
Scout
快速扫描潜在攻击面。
目标:
高召回
宁可多找一点。
Analyst
理解:
- 数据流;
- 权限;
- 调用关系;
- 用户可控输入;
- 敏感 Sink。
Skeptic
专门反驳:
“为什么这不是漏洞?”
找:
- 前置校验;
- 不可达路径;
- 管理员限制;
- 类型约束;
- 框架自动保护。
Validator
在受控环境里验证可复现性。
Reporter
只有证据达到阈值,才进入人工队列。
为什么 Skeptic Agent 很重要
多数多 Agent Demo 的第二个 Agent 是:
Reviewer
但 Reviewer 很容易只是换一种语言同意第一个模型。
更有用的 Prompt 应该故意对抗:
你的任务不是证明漏洞存在。
你的任务是尽最大努力证明这个结论是误报。
这会产生真正的:
Adversarial Review
一个 Finding 不应该只有 description
最少:
public record VulnerabilityFinding(
String findingId,
String repository,
String commit,
String file,
int startLine,
int endLine,
String vulnerabilityClass,
AttackPrecondition precondition,
List evidence,
List counterEvidence,
ValidationStatus validation,
double confidence) {
}
其中最容易被漏掉的是:
CounterEvidence
不是只记录“为什么像漏洞”,还记录“有哪些证据说明它可能不是”。
代码审计 Agent 最怕上下文切错
例如:
sanitize()
定义在另一个模块。
如果 Agent 只看到当前函数,它可能误报。
所以 Repository Context Builder 很关键。
我会按 Finding 动态装配:
当前函数
调用者
被调用函数
鉴权中间件
相关类型
配置
测试
而不是简单把整个仓库塞进 1M Context。
Call Graph 和 LLM 应该组合
确定性工具先生成:
AST
Call Graph
Dependency Graph
Taint Candidate
LLM 再解释:
这条路径在业务上是否可利用
这比纯 LLM 从几十万行源码里自由搜索稳定得多。
一个最小 Pipeline
Repo Snapshot
↓
Static Extraction
↓
Candidate Entry Points
↓
Scout Agent
↓
Semantic Analysis
↓
Skeptic Review
↓
Sandbox Validation
↓
Human Security Review
↓
Disclosure / Fix
注意顺序。
不是:
LLM → CVE
为什么要固定 Commit
安全扫描结果必须绑定:
repository
commit_sha
否则今天发现:
foo.java:128
明天代码一变,证据就无法复现。
所有 Finding 都应该基于不可变 Snapshot。
真实代码仓库泄露以后,时间就是关键变量
Google 文章的背景非常现实:攻击者拿到企业源码以后,也可以用 AI 快速找漏洞。
这时候防守方过去的流程:
人工分模块
→几周代码 Review
→修复
可能已经太慢。
这就是为什么 AVDH 在事件响应里有意义:
谁先发现可利用路径
谁先修
变成时间竞赛。
但不要把安全 Agent 接到生产代码以后自动修
至少第一阶段不要。
原因:
误报可能改坏业务
漏洞修复可能破坏兼容
补丁可能只遮住表面
安全变化本身需要 Review
更合理:
Agent 找
Agent 验
Agent 生成 Patch Candidate
Human Review
测试
Canary
漏洞验证环境必须隔离
如果系统可以自动构造攻击输入,验证 RCE、SQL Injection、SSRF 等风险,绝对不能直接在生产网络测试。
需要:
Sandbox
No Production Credentials
Restricted Network
Synthetic Data
Disposable Environment
并给每类验证设策略。
我会给验证 Tool 加 Risk
public record SecurityTool(
String name,
SecurityActionType type,
RiskLevel risk,
boolean sandboxOnly,
boolean humanApprovalRequired) {
}
例如:
AST parse
LOW
Local fuzz
MEDIUM
Exploit validation
HIGH
External target scan
CRITICAL
高风险动作必须被平台硬限制。
“找到了 100+ Critical”不是唯一指标
如果评价安全 Agent,我会看:
True Positive Rate
Critical Recall
False Positive / KLOC
Human Review Minutes / Finding
Time to Validated Finding
Duplicate Finding Rate
Patch Acceptance Rate
以及最关键的:
Missed Critical
一个公开 CVE 数量也不能直接等于模型能力
12 个 CVE 是很强的现实证据,但它仍然混合了:
- 模型;
- Harness;
- Mandiant 专家经验;
- 静态分析;
- 验证;
- 人工 Disclosure。
所以我不太喜欢把这种案例写成:
Gemini 自动发现 12 个 CVE
更准确的是:
专家设计的 Agentic Harness
让模型能力变成了可重复安全流程
这才是能复制的部分。
安全 Agent 的 Prompt 反而不应该太自由
例如 Scout 输出必须遵循:
{
"entry_point": "...",
"user_controlled_input": "...",
"sensitive_sink": "...",
"required_privilege": "...",
"attack_path": ["..."],
"missing_evidence": ["..."]
}
不能只给:
“这里可能有一个严重漏洞。”
结构化结果才方便后续 Skeptic 和 Validator 消费。
证据必须能被人快速确认
安全工程师最不想看到的是:
模型写 2000 字解释
最想看到:
Source
→ Transformation
→ Sink
→ Missing Check
→ Reproduce
例如:
POST /upload
→ filename
→ path.join(root, filename)
→ no canonicalization
→ filesystem write
一分钟就能判断是否值得继续。
我很认同 AVDH 背后的一个方向
AI 不一定要替代最强的安全专家。
更现实的价值是把专家从:
海量普通代码检查
里解放出来,专门处理:
复杂利用链
业务逻辑漏洞
架构级问题
真正高价值目标
Google 文章最后也明确强调的是“human expertise multiplier”。
这比“全自动黑客 Agent”更接近生产价值。
如果企业今天开始做,我会从哪里开始
不要一开始扫全公司。
先选:
一个 Web 服务
10—30 万行代码
有完整测试环境
有安全专家参与
建立 50—100 个历史漏洞/已修复问题作为评测集。
比较:
传统 SAST
LLM 单 Agent
多 Agent Harness
看:
Recall
Precision
Review Time
Cost
最后一个判断
AVDH 最值得企业安全团队关注的,不是“Agent 会不会自动找到零日”。
更重要的是:它展示了一种新的代码审计生产线。
过去:
扫描器出结果
→人过滤海量告警
现在可能变成:
静态工具提供候选
→Agent 理解上下文
→另一个 Agent 主动反驳
→Sandbox 验证
→人只看高价值证据
这套流程真正把 AI 的语义能力放在了传统扫描器和人类专家中间。
而不是让一个大模型坐在最上面,宣布“这里有漏洞”。
两天 100+ Critical、12 个 CVE 的真正意义,我觉得就在这里:不是模型更会猜漏洞,而是安全团队开始拥有一条可以规模化运行的 AI 审计流水线。
Finding 也需要生命周期,不是发现以后就“Open”
我会设计:
public enum FindingStatus {
CANDIDATE,
UNDER_SKEPTIC_REVIEW,
NEEDS_CONTEXT,
VALIDATION_QUEUED,
VALIDATED,
REJECTED_FALSE_POSITIVE,
HUMAN_CONFIRMED,
PATCH_PROPOSED,
FIXED,
DISCLOSED
}
这样安全团队能看到漏斗,而不是一片红色告警。
人工安全专家应该把时间花在哪里
理想状态不是人完全退出,而是把人放在高价值节点:
模型争议
高危验证
业务逻辑
Exploit Chain
Patch Review
Disclosure
普通候选搜索、重复验证和证据整理尽量交给 Harness。
这也是为什么“节省多少人工小时”不一定是唯一目标。
安全团队更关心:
同样 10 个专家
能覆盖多少倍代码
一个非常实际的误报复盘机制
每个被人判为 False Positive 的 Finding,不应该直接关闭。
提取原因:
AUTH_GUARD_PRESENT
UNREACHABLE_CODE
SANITIZED_UPSTREAM
TEST_ONLY_CODE
FRAMEWORK_PROTECTED
INVALID_DATAFLOW
下一轮 Skeptic Agent 可以利用这些标签做专门训练和评测。
一个月以后就能回答:
我们最大的误报来源是什么?
安全 Agent 的知识库和业务 RAG 不应该混用
安全上下文通常包含:
- Framework Security Semantics;
- CVE;
- Internal Secure Coding Rules;
- Historical Findings;
- Architecture;
- Threat Model。
这些数据权限往往更高。
建议使用独立安全知识域,甚至独立 Vector Store / Artifact Store,避免普通 Agent 检索到漏洞细节、攻击路径和未披露问题。
最后的发布门禁应该看“验证后的风险”,不是 Candidate 数量
一个 Agent 版本从:
10,000 Candidates
变成:
30,000 Candidates
不代表变强。
如果 Human Confirmed 没增加,Review 成本反而涨了。
真正的优化目标更接近:
Validated Critical / GPU-hour
Human-confirmed / Review-hour
Critical Recall
False Positive Rate
这才符合安全团队的生产目标。
更多企业级 AI 应用、Agent、RAG 与模型工程化内容,我会继续整理在 智元界:
https://www.zyentor.com/