用 LLM 保护源代码安全:Anthropic 六步闭环实战指南

从威胁建模到自动修复,瓶颈已从发现转移到验证与修复

Posted by 爱折腾的工程师 on Tuesday, June 2, 2026

引言

模型能力正在快速且不均匀地进化。Anthropic 安全团队在与多个企业合作扫描开源软件的过程中,截至 2026 年 5 月 22 日已披露 1,596 个漏洞,但其中仅 97 个被修复。这组数据揭示了一个关键洞察:

发现已经可以轻松并行化,瓶颈已经转移到验证、分类和修复。

本文基于 Anthropic 官方博客 Using LLMs to secure source code 的核心内容,面向安全工程师与平台架构师,提炼其"防御者闭环"六步方法论的关键策略与实践洞察。

防御者闭环


防御者闭环:六步方法论

那些找到并修复最多漏洞的团队,最终收敛到一套六步流程的变体:

  1. 威胁建模 — 在扫描前定义什么算漏洞
  2. 沙箱 — 构建隔离环境以安全运行代理并验证可利用性
  3. 发现 — 让模型在源码中寻找漏洞
  4. 验证 — 独立确认发现是否真正可利用
  5. 分类 — 去重、定级、排序修复优先级
  6. 修复 — 应用补丁、确认漏洞失效、搜索变体

前两步是一次性基建投入(威胁建模+沙箱),后四步构成持续循环。首次扫描产出最多,后续轮次发现更少但更复杂的漏洞。

六步闭环流程


第一步:威胁建模 — 定义什么算漏洞

为什么重要:误报最常见的原因是模型缺乏对信任边界的理解。模型可能将受信配置文件标记为攻击面,也可能将面向互联网的服务误认为内部服务而漏报。

两步构建威胁模型

1. 从代码、文档和漏洞历史中引导

把你交给新安全工程师第一天的全部资料喂给模型:架构文档、Wiki、入口点、Git 历史、历史漏洞。让模型创建包含系统上下文、资产、入口点和信任边界的威胁模型。

一个团队回顾了数百个历史 CVE 和安全修复提交,提炼为"bug 形状"提示,问了模型两个问题:修复是否完整?是否在其他地方也应用了?他们在一小时内发现了三个可利用的问题。

2. 让模型采访系统专家

参考 Shostack 四问框架:我们在构建什么?什么可能出错?我们在做什么应对?我们做得好吗? 先运行引导步骤生成草稿,让受访者从草稿开始而非从零构建。

关键实践

  • 考虑依赖项的安全策略 — 如 vLLM 的 security.md、SQLite 的"黑魔法防御"
  • 明确声明什么是受信的 — 如果你信任配置文件或已认证客户端,在威胁模型中记录
  • 在代码仓库中放置 THREAT_MODEL.md — 发现代理在扫描前可以读取它,跳过已知非问题

一个团队扫描大型项目时有 40% 的误报率。深入分析后发现:发现是可复现的、PoC 也证明了可利用性,但代码负责团队拒绝承认,因为这些 bug 不符合项目的威胁模型。


第二步:沙箱 — 安全运行代理并验证可利用性

沙箱有两个目的:保护你的系统 + 证明可利用性

保护系统

一个团队告诉模型它没有网络访问——但实际上有——结果模型发现自己可以从 GitHub 拉取内容。另一个团队观察到代理在扫描中途去回答了一个 GitHub Issue。

最佳实践

  • 匹配隔离级别与威胁模型:容器适合发现代理读代码,微虚拟机(如 Firecracker)用于运行目标和 PoC
  • 仅在设置阶段给网络访问,之后快照并断网
  • 运行期仅允许通过本地代理路由到模型 API 的流量
  • 绝不将凭据(~/.aws~/.ssh.env)暴露给代理

证明可利用性

静态扫描时模型只能假设什么可能出错,无法测试路径是否可达。当团队构建了可编译代码、运行测试、引爆 PoC 的沙箱后,不可利用的发现显著下降

一个攻防团队的评估是:“最大的效能杠杆是给模型测试床、活系统,以及运行 PoC。”

关键原则

  • 固定一切:镜像标签、commit SHA、依赖、构建命令
  • 忠实于生产环境:排除依赖(如队列/存储)会导致漏报;忽略生产防御(如 WAF)会导致不可利用的误报
  • 如果构建沙箱不现实,先从纯源码分析的发现步骤开始——前沿模型仅从源码分析就能有效发现漏洞

第三步:发现 — 丰富上下文、简短提示、实用工具

提示策略(反直觉)

前沿模型受益于越来越简单的提示。过于规范的提示反而降低发现效果——长清单会减少模型的创造性。

有效做法

  • 提供目标和上下文 — 说明"为什么"和"什么",把"如何扫描漏洞"留给模型
  • 尝试指定特定漏洞类别 — 描述漏洞类别、它做什么、通常在哪里出现
  • 定义输出格式 — 要求结构化报告(理由、发现、影响、严重度),包含弱发现的提前退出机制

并行化策略

让模型先做一次全局扫描将搜索空间分区(按攻击面/端点/组件),然后将分区喂给并行发现代理。最后运行系统级扫描,将分区级发现作为上下文。

暴力横向扩展会快速遇到收益递减。一个团队:“我们最初尝试水平扩展派出更多代理,但发现回报递减。“另一个团队增加并行代理后得到"大量问题”,其中大部分互相重复。

工具支持

  • 基础:grep、glob 等代码搜索工具
  • 专业:SAST 扫描器、Fuzzer
  • 自适应:让模型按需构建自己需要的工具

第四步:验证 — 过滤不可利用的发现

核心原则:发现优化召回率,验证优化精确率。 两者不应混在同一步——混合时模型会自我审查,过滤掉本应确认的真正漏洞。

独立验证

  • 验证代理必须独立于发现代理:全新容器、无共享文件系统或对话历史
  • 仅给验证代理 (1) PoC/书面发现 + (2) 代码库
  • 提示验证代理反驳发现代理的结论——假设每个发现是误报,搜索它错误的原因

多投票机制

如果单次验证仍有太多不可利用的发现通过,尝试多个独立验证者,取多数票。还可以引入独立"裁判"来裁定发现与验证代理的分歧。

跨团队数据表明,添加对抗性验证者大约将不可利用发现率减半;要求验证者也构建确认利用的 PoC,误报率接近


第五步:分类 — 按根因去重,按前提条件和影响定级

为什么关键

多个团队分享了相同的教训:如果我们发给产品工程师一堆大部分不可利用的发现,他们会失去信任然后放弃阅读——即使其中有需要立即修复的。

去重策略

  1. 廉价确定性通道:相同文件、相同类别、漏洞行号差在 10 行以内
  2. 模型定性规则
    • 视为重复:同一根因不同措辞;同一漏洞多个调用点;缺少全局保护按端点报告
    • 视为独立:同文件不同漏洞类别;不同变量到达不同 sink;同一辅助函数中两个独立 bug

定级维度

维度 关键问题
可达性 攻击者能否从真实入口到达此代码?
攻击者控制 不受信输入是否完整到达 sink?
前提条件 需要什么才能触发?非默认设置?特定时间窗口?
认证 未认证用户能否触发?
读 vs 写 攻击者只能读还是也能修改?
爆炸半径 影响一个用户还是整个平台?

规则:零前提+未认证远程 = 严重/高;1-2 个前提或需认证 = 中;3+ 前提或仅本地 = 低。


第六步:修复 — 闭环并改善下一轮上下文

TDD 修复流程

  1. 写测试:在修复前写一个会失败的新测试
  2. 实现修复:确认测试通过且不破坏其他功能
  3. 搜索变体:(1) 同模式——其他调用点或相同 bug 代码的副本;(2) 同类别——有一个 SQL 注入的代码库往往有更多

验证阶梯

层级 检查 目的
① 构建 补丁编译通过、新测试通过 基本正确性
② 复现 原始 PoC 停止工作 捕获无效补丁
③ 回归 原始测试套件仍通过 捕获破坏性/过度限制补丁
④ 反攻 新发现代理做对抗性检查 捕获不完整补丁

一个渗透测试团队发现生成的补丁质量参差不齐——直到他们告诉模型通过重新运行 PoC 来验证补丁。给模型反馈来迭代后,补丁质量飞跃提升。

常见陷阱

  • 模型倾向于在特定调用点窄范围修复,而非根因
  • 推荐的补丁往往过度限制,可能打断与其他服务的连接
  • 解决方案:提示"最小化修改修复根因——不重构、不顺手清理、不重格式化”

实践启示

1. 首次扫描后的投资顺序

你的第一次扫描会产出比预期更多的发现。大部分需要验证和分类。先为扫描之后的管道预算,再为更多扫描预算。

2. 持续扫描节奏

  • 首次迭代:多次运行循环,根据新发现数量和风险容忍度决定何时停止
  • 之后:(1) 定期扫描 或 (2) 每次代码有重大变更时扫描

3. 事件驱动集成

领先团队已将漏洞扫描连接到事件流:

  • Bug 赏金报告触发自动变体分析
  • 安全评审触发扫描并附上候选发现
  • 已验证漏洞更新静态分析工具以防止未来出现

4. 配套资源


总结

模型找到并利用代码漏洞正变得越来越容易。防御者的工作是在攻击者利用之前找到并修复漏洞。六步闭环方法论——威胁建模、沙箱、发现、验证、分类、修复——提供了一套可重复、可扩展的实践框架。

关键记住:瓶颈不再是发现,而是之后的一切。 投资在验证流水线、信任边界文档和对抗性检查上,收益远大于单纯增加扫描并行度。


参考来源:Using LLMs to secure source code,Anthropic,2026-05-27

「真诚赞赏,手留余香」

爱折腾的工程师

真诚赞赏,手留余香

使用微信扫描二维码完成支付