用多智能体代码审查抢在对手之前发现漏洞

2026-08-18 32 预计阅读时间: 1 分钟
来源: cloud.google.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:17 分钟

生成式 AI 正在把攻击者的代码分析和漏洞利用速度推向机器级别。面对被窃取的企业代码仓库,防守方如果仍依赖完全手工的源代码审查,往往很难在攻击者之前完成定位、验证和修复。

一种更可行的思路,是把大模型放进一个严格编排的安全分析流水线:让不同智能体分别负责代码侦察、威胁建模、入口发现、上下文补全、假设生成和结果验证,再由安全专家进行最终判断。Mandiant 分享的 Agentic Vulnerability Discovery Harness(AVDH)正是这种架构的一个实践案例。

从“让模型看代码”转向“让流程约束模型”

大模型擅长理解复杂代码和跨文件关系,但它也具有非确定性:同一段代码可能得到不同结论,模型还可能忽略权限、路由、配置或运行时条件。单次提问很难承担严肃的漏洞审查任务。

AVDH 的关键不只是使用了某个模型,而是建立了一个由程序控制的多阶段 Harness。每个阶段有明确输入、输出和质量门槛,智能体按照顺序推进,最终生成供人工审核的风险排序结果。

典型流程可以抽象为:

  1. 代码侦察与威胁建模:识别应用类型、核心组件、暴露面和不应纳入分析的目录。
  2. 入口发现:扫描 HTTP 路由、IPC 监听器及其他领域相关的攻击入口,并提取用户输入。
  3. 上下文补全:沿着函数调用、权限检查、清洗器和数据存储边界收集相关代码。
  4. 假设生成:分别从访问控制和数据流角度提出潜在漏洞假设。
  5. 假设验证:使用多个独立验证智能体交叉检查,再由合成智能体作出确认、推翻或拒绝的结论。
  6. 人工验证:通过动态测试和 Proof of Concept 验证可达性、可利用性以及是否存在补偿性控制。

这种结构把“模型自由发挥”限制在具体阶段内。模型仍然负责理解和推理,但程序负责调度、聚合、去重、风险分级和人工交接。

威胁模型必须成为第一道闸门

代码安全分析最容易犯的错误,是脱离应用实际运行方式讨论某个危险函数。一个管理员专用接口和一个普通用户可访问的接口,风险完全不同;一段从未执行的测试代码,也不应和生产路径获得相同优先级。

因此,流水线应先回答几个问题:

  • 目标软件属于 Web、桌面、服务端还是其他领域?
  • 哪些组件能被外部用户、低权限用户或内部服务触达?
  • 身份认证和授权检查位于哪里?检查的是谁的身份?
  • 哪些路由、IPC 监听器、消息消费者或任务入口接收用户控制的数据?
  • 哪些目录是测试、构建产物、示例或第三方依赖,不应直接纳入分析?
  • 关键组件之间如何连接,输入经过哪些清洗、转换和存储边界?

在 AVDH 的做法中,Explorer 智能体先建立软件全貌,再派发 Specialist Explorer 分析认证、授权、路由等领域,最后由 Threat Model Synthesis 智能体生成统一威胁模型。安全顾问在继续分析前检查文本和可视化结果,相当于给自动化流程加了一道审批门。

这道门很重要。威胁模型如果错了,后续分析即使找到了大量“危险代码”,也可能因为缺少可达性和业务上下文而产生大量误报;更严重的是,模型可能把真正重要的攻击路径排除在外。

控制流与数据流要分工分析

漏洞通常不是一个孤立函数造成的,而是入口、权限、调用链、数据变换和危险操作共同形成的结果。将所有任务交给一个通用智能体,会让上下文过于庞杂,也不利于定位漏检原因。

可以把分析拆成两个互补方向:

  • 访问控制分析关注控制流:入口是否需要认证,权限是否检查,检查是否针对正确主体,敏感操作是否能被低权限用户调用。这类分析可以发现缺失授权、权限提升和 CSRF 等问题。
  • 数据流分析关注输入如何移动:用户输入是否经过校验和清洗,是否跨越数据库、文件系统或命令执行边界,最终是否抵达危险 Sink。这类分析可以发现 SQL 注入、XSS、命令注入和路径遍历等问题。

上下文补全智能体负责把入口附近看似无关的代码找回来。例如,一个路由处理函数可能只调用了服务层方法,真正的权限判断位于更深的中间件,危险的字符串拼接则发生在另一个文件中。只看入口文件,无法判断完整攻击链。

一个可改造的最小流水线示例

下面是一个不依赖外部模型 SDK 的 Python 示例,用确定性的函数模拟多智能体编排。它展示了如何把阶段、质量门槛和人工交接写成可审计的程序。接入实际模型时,可以将各阶段函数替换为 Google ADK 或其他编排框架中的 Agent 调用,并保留输入输出契约。

运行前只需要保存为 avdh_demo.py,执行 python avdh_demo.py。示例不会扫描真实代码,也不会执行利用代码。

from dataclasses import dataclass
from typing import List


@dataclass
class Finding:
    title: str
    severity: str
    evidence: str
    status: str = "candidate"


def explore(repo: str) -> dict:
    return {
        "repo": repo,
        "domain": "web application",
        "in_scope": ["src/routes.py", "src/services.py"],
        "excluded": ["tests/", "vendor/"],
        "entry_points": ["POST /admin/export"],
    }


def build_threat_model(recon: dict) -> dict:
    return {
        "domain": recon["domain"],
        "entry_points": recon["entry_points"],
        "assumptions": [
            "The endpoint is reachable by an authenticated user.",
            "Export authorization must be checked against the requesting user.",
        ],
    }


def generate_hypotheses(model: dict) -> List[Finding]:
    # In production, this stage would call access-control and data-flow agents.
    return [
        Finding(
            title="Possible missing authorization on export endpoint",
            severity="high",
            evidence="POST /admin/export reaches export_data without a role check",
        )
    ]


def validate(hypothesis: Finding, model: dict) -> Finding:
    # Replace with independent validators and a synthesis agent.
    if "authorization" in hypothesis.title.lower():
        hypothesis.status = "confirmed"
    else:
        hypothesis.status = "rejected"
    return hypothesis


def human_gate(findings: List[Finding]) -> List[Finding]:
    # A real review must reproduce reachability and test compensating controls.
    return [finding for finding in findings if finding.status == "confirmed"]


def main() -> None:
    recon = explore("sample-repository")
    threat_model = build_threat_model(recon)
    print("Threat model:", threat_model)

    candidates = generate_hypotheses(threat_model)
    validated = [validate(item, threat_model) for item in candidates]
    confirmed = human_gate(validated)

    for finding in confirmed:
        print(f"[{finding.severity.upper()}] {finding.title}")
        print("Evidence:", finding.evidence)
        print("Next step: reproduce safely in an isolated test environment")


if __name__ == "__main__":
    main()

这个示例有三个值得保留的设计点。第一,威胁模型在假设生成前完成;第二,候选发现和确认结果分开保存,避免把模型的初步猜测直接当作漏洞;第三,人工闸门是显式阶段,而不是一句模糊的“请专家复核”。在真实系统中,还应为每个阶段记录模型版本、提示词版本、规则版本、输入文件范围和最终裁决。

高温验证与低温执行并不矛盾

漏洞假设生成和漏洞结论确认适合不同的模型配置。生成阶段的目标是扩大覆盖面,可以允许智能体提出更多可能性;验证阶段则需要独立视角,避免一个智能体的早期判断影响所有后续结论。

AVDH 的验证阶段会并行调度多个较高温度的 Validation agent,让它们从不同角度审查同一个假设,再由 Validation Synthesis agent 汇总证据。最终结果分为三类:

  • Confirmed finding:假设具有充分证据,并通过独立验证。
  • Disproven hypothesis:存在明确证据反驳漏洞成立。
  • Rejected hypothesis:不符合威胁模型,或不满足漏洞定义。

这里的高温不是为了让输出更“有创意”,而是为了增加验证路径的多样性。实际部署时仍需通过基准测试确定温度、模型和并发度,不能把某个参数配置当成通用答案。

把专家经验做成可维护的规则系统

仅依赖人工复核可以降低误报,却不能充分解决漏报。要提高召回率,需要把安全顾问长期积累的经验注入整个流水线,而不是只写在某个大提示词里。

一种可维护的组织方式,是把规则分成三层:

  • 软件领域规则:说明 Web、桌面、微服务等不同软件类型的常见攻击面和分析重点。
  • 语言与框架规则:描述特定语言、路由框架、ORM、认证中间件和库的入口模式及特殊行为。
  • 漏洞规则:定义某一类漏洞的发现方法、验证要求和风险评级标准。

语言和框架规则可以作用于整个流水线,帮助侦察、入口识别和上下文补全;漏洞规则则主要在后期使用,指导智能体如何验证 SQL 注入、命令注入、权限缺失等具体问题。

规则系统应当模块化、可版本化,并且参与基准测试。每次修改规则,都要知道它提升了哪些漏洞类型的召回率,又引入了多少误报。

用专有基准集衡量真实能力

公开漏洞数据集适合快速入门,但不一定适合作为唯一评测依据。现代模型可能在训练阶段接触过公开仓库,测试结果有可能反映记忆,而不是对新代码的推理能力。

可以这样实践:建立一组由安全人员人工注入并验证的合成代码库,覆盖不同语言、框架、软件架构和漏洞深度。每个漏洞都必须确认真实可达,并在隔离环境中动态验证。

评测流程至少需要处理三类问题:

  • 漏报:基准中的真实漏洞是否被发现?
  • 误报:没有对应真实问题的发现是否确实是误报?
  • 重复发现:多个结果是否指向同一个根因?

对非确定性模型,单次运行的结果不足以说明能力。应在多个代码库、多个架构和多次运行上取平均,并让人工专家检查 Grading agent 的判断。与此同时,要防止提示词和规则对固定基准集过拟合,定期加入未公开的保留测试集。

适合落地的两层防御策略

这类 Harness 更适合点时、深度和目标明确的任务,例如:

  • 被窃取代码仓库的事件响应调查
  • 红队和渗透测试前的源代码分析
  • 高风险应用上线前的定向审查
  • 复杂漏洞链和潜在零日问题的主动发现

它不应被当作完全自动化的漏洞发布机器。真正的确认仍需要专家检查调用链、运行配置、权限边界和补偿性控制,并在隔离环境中复现攻击条件。没有动态验证的“高危”结果,最多只能称为待验证假设。

在持续防御场景中,可以将点时深度分析和持续扫描结合:持续扫描负责保持开发生命周期中的可见性,Agentic Harness 负责针对关键资产和复杂攻击链进行集中分析。两者的结果应统一进入漏洞管理流程,避免同一问题在不同工具中重复计数。

落地检查清单

  • 明确威胁模型,并设置人工审批门。
  • 为侦察、入口发现、数据流、访问控制和验证定义独立输出契约。
  • 使用上下文补全追踪跨文件、跨函数和跨组件的数据流。
  • 将候选假设、确认发现、推翻结论和拒绝结果分开存储。
  • 把语言、框架和漏洞知识做成可版本化规则。
  • 对每个确认发现执行安全的动态复现和 PoC 验证。
  • 使用专有、可达、可利用的基准集持续评测召回率和误报率。
  • 记录模型、提示词、规则、代码快照和裁决过程,保证结果可审计。
  • 将自动化定位能力用于释放专家时间,而不是取消专家责任。

防守方要追上对抗性 AI,关键不是寻找一个能够独立完成安全审查的模型,而是构建一条能被验证、能被复现、能吸收专家经验的工程流水线。模型负责扩大分析范围,Harness 负责约束过程,安全专家负责确认现实世界中的攻击成立条件。三者结合,才可能把代码可见性真正转化为可执行的防御速度。


相关推荐