我用 Claude Code 造了一个代码审计 Skill,它在 20 万行项目中找到了 63 个漏洞
嗯,用户让我帮忙总结一下这篇文章的内容,控制在100字以内,而且不需要用“文章内容总结”这样的开头。好的,首先我需要通读整篇文章,抓住主要观点。 文章主要讲的是一个审计Skill的设计,用于代码审计。作者提到传统方法在大项目中效果不佳,容易出现幻觉问题。所以他们设计了一个系统来解决这些问题。 核心部分包括防幻觉原则、多阶段审计流程、Agent合约等。这些机制确保了审计的准确性和效率。比如,禁止编造代码片段,使用动态Agent分配,还有覆盖率检查。 实战案例显示这个Skill在大型项目中发现了多个严重漏洞。最后还对比了传统工具,指出其优势在于语义理解和数据流追踪。 总结一下,文章详细介绍了这个Skill的设计思路和实际应用效果。现在我要把这些要点浓缩到100字以内。 </think> 文章介绍了一个用于代码审计的AI Skill设计,重点解决大项目中传统方法的不足。通过防幻觉规则、多阶段审计流程、动态Agent分配和覆盖率检查等机制,确保准确性和效率。实战案例展示了其在大型Java项目中发现关键漏洞的能力,并与传统工具进行了对比。 2026-2-10 09:53:28 Author: www.freebuf.com(查看原文) 阅读量:1 收藏

一、背景:为什么要做一个审计 Skill?

用大模型做代码审计,最直觉的方式是:

"帮我审计这个项目的安全漏洞"

这在小项目上偶尔有效,但在真实的工程项目中几乎不可用。原因很简单: 代码审计不是搜索,而是决策。 一个 20 万行的 Java 项目,有上百个 Controller、几十个数据源、复杂的认证链路。模型不知道该先看什么,不知道该看多深,不知道什么时候该停。更致命的是——它会「幻觉」:报告一个根本不存在的文件中的漏洞,或者编造一段从未出现过的代码。

二、核心设计哲学

在写第一行 Skill 指令之前,我花了很多时间思考一个问题:

AI 做代码审计,最容易犯什么错? 答案是两个字:幻觉

2.1 防幻觉:宁可漏报,不可误报

这是整个 Skill 的第一原则。具体体现为三条硬性规则:

 禁止猜测文件路径——必须用 Glob/Read 验证文件存在  
 禁止编造代码片段——必须引用 Read 工具实际输出的代码  
 禁止报告未读文件中的漏洞——没有读过的代码不能出现在报告中

2.2 反确认偏见:方法论驱动,而非经验驱动

另一个容易出现的问题是确认偏见。模型读了几个文件后,会倾向于「证实」自己已有的判断,而不是系统性地检查所有可能。

 禁止 "基于之前的审计经验,我将重点关注..."  
 禁止因为某个漏洞类型"看起来不太可能"就跳过检查  
 必须枚举所有敏感操作,然后逐一验证  
 必须完成完整的检查清单,对每个维度一视同仁

2.3 攻击链思维:漏洞不是孤岛

单个 Medium 级别的漏洞可能无关紧要,但当它与另一个 Medium 组合时,可能变成 Critical。

认证绕过(H) + 需认证的 SSRF(M) = 未认证 SSRF(C)  
信息泄露(L) + 密码重置逻辑缺陷(M) = 账户接管(C)

三、审计架构:五阶段模型

整个审计流程分为五个阶段:

Phase 1: Reconnaissance(侦察)  
    ↓  
Phase 2A: Vulnerability Hunt(自由审计)  
    ↓  
Phase 2B: Coverage Verification(覆盖率自检)  
    ↓  
Phase 3: Deep Dive(深度验证)  
    ↓  
Phase 4: Report(报告生成)

Phase 1:侦察

不急着找漏洞,先画地图。 这个阶段做的事情非常明确:

  1. 识别技术栈 — 语言、框架版本、数据库、中间件
  2. 枚举攻击面 — 有多少 API 端点?有哪些数据源?认证链路怎么走?
  3. 发现功能模块 — 文件上传、数据导出、数据源管理、用户管理...
  4. 确定审计维度 — 哪些安全维度需要重点关注?

Phase 2A:自由审计 + 多智能体并行

这是核心阶段。多个 Agent 并行执行,每个 Agent 负责 1-3 个安全维度。 Skill 不预设固定的 Agent 模板,而是根据 Phase 1 的攻击面分析动态决定:

该项目的 R1 Agent 划分(基于攻击面分析动态生成):  
Agent 1: SQL/SpEL 注入 (D1) — 追踪用户输入到 SQL Sink  
Agent 2: 认证+授权+业务逻辑 (D2+D3+D9) — JWT/Filter/权限/IDOR  
Agent 3: 文件操作+SSRF (D5+D6) — 上传下载/路径遍历/JDBC URL  
Agent 4: 反序列化+RCE (D4) — JAR 上传/类加载/反射调用  
Agent 5: 配置+加密+依赖 (D7+D8+D10) — 硬编码密钥/暴露端点/CVE

Phase 2B:覆盖率自检

这是区别于其他 AI 审计工具的关键机制。 Phase 2A 完成后,不是直接出报告,而是用一个 10 维度覆盖率矩阵 做自检:

---|---|---
D1 | 注入 | 用户输入是否能到达 SQL/Cmd/LDAP/SSTI 执行点?
D2 | 认证 | Token 生成、验证、过期是否完整?
D3 | 授权 | 每个敏感操作是否验证用户归属?
D4 | 反序列化 | 是否存在不受信数据的反序列化?
D5 | 文件操作 | 上传/下载路径是否可控?
D6 | SSRF | 服务端 HTTP 请求的 URL 是否用户可控?
D7 | 加密 | 硬编码密钥?弱算法?
D8 | 配置 | 调试接口暴露?CORS 过宽?
D9 | 业务逻辑 | 竞态条件?流程可跳过?
D10 | 供应链 | 依赖是否有已知 CVE?

四、增量补漏:R2 不重复 R1

这是 Skill 中我花了最多时间优化的部分。

4.1 问题:多轮审计的 Token 浪费

早期的多轮审计策略很粗暴——R2 重新来一遍,只是换个方向。结果:

  • R2 重复搜索 R1 已确认干净的方向(~30% 浪费)
  • R2 重复读取 R1 已读过的文件(~20% 浪费)
  • R2 Agent 数量不随缺口递减(~15% 浪费)

4.2 解决方案:跨轮传递结构

R1 完成后,主线程会产出一个结构化的「跨轮传递结构」:

COVERED:  D1( 10个发现), D2( 6个), D3( 14个), D5( 4个), ...  
GAPS:     D4( 未覆盖), D9( 未覆盖), D1(️ SQL查询构建层未深入)  
CLEAN:    [JNDI/XXE/Fastjson — 已搜索确认不存在的攻击面]  
HOTSPOTS: [QueryBuilder.java:135 — 字符替换未追踪, PermissionManager.java — 鉴权逻辑待验证]  
FILES_READ: [TokenUtils.java:JWT decode无verify, CryptoUtils.java:硬编码AES密钥, ...]  
GREP_DONE: [JWT.decode, @Permission, CREATE ALIAS, loadRemoteFile, ...]

4.3 R2 Agent 数量自适应

R2 不再固定数量,而是由缺口数精确计算:

缺口状态 R2 Agent 数量
未覆盖 0-1 个 1 Agent (20 turns)
未覆盖 2-3 个 2 Agent (2×20 turns)
未覆盖 4+ 个 3 Agent (3×20 turns)

五、Agent 合约:让每个智能体可控

多智能体最大的挑战不是「如何启动」,而是「如何约束」。 Skill 定义了一套 Agent 合约(Agent Contract) ,每个 Agent 启动前自动注入:

---Agent Contract---  
1. 搜索路径: {paths}。排除: node_modules, .git, build, test, frontend  
2. 必须使用 Grep/Glob/Read 工具。禁止 Bash 中 grep/find/cat。  
3. 工具调用 ≤50 次,Bash ≤10 次。max_turns: {N}。  
4.  Turn 预留: turns_used ≥ max_turns-3 时立即停止探索,产出结构化输出。  
5. 搜索策略: Grep 定位行号 → Read offset/limit 读上下文(±20行)。  
6. 输出: 按结构化模板返回。禁止返回大段原始代码(>3行)。  
7. 同类漏洞 ≥5 个合并报告。同 pattern 多文件列清单不逐个深挖。  
8. Sink 类别上界: 每维度最多 8 个 Sink 类别,每类最多深追 3 个实例。  
9. 数据转换管道追踪: Source → [Transform₁ → ... → Transformₙ] → Sink。  
10.  截断防御: HEADER 在最前(≤400字),AGENT_OUTPUT_END 在最后。  
---End Contract---

六、两层检查清单:Checklist 不驱动审计

很多安全工具的做法是:给一个检查清单,逐项执行。 我的设计理念正好相反:Checklist 不驱动审计,而是验证覆盖。

LLM 先自由审计(Phase 2A)→ 再用矩阵查漏(Phase 2B)

七、实战案例:某大型 Java BI 平台审计全记录

7.1 项目概况

指标 数据
项目 某开源 BI 数据可视化平台
代码量 ~200K 行 Java
技术栈 Spring Boot 3.x + Java 21 + MyBatis-Plus + 嵌入式数据库
模块结构 core-backend + sdk-common + extensions (多数据源插件)
审计模式 Standard(2 轮)

7.2 审计执行过程

Round 1(侦察 + 广度扫描)

Agent 方向 max_turns 发现数
Agent 1 SQL/SpEL 注入 (D1) 25 8
Agent 2 认证+授权 (D2+D3) 25 16
Agent 3 文件+SSRF (D5+D6) 25 6
Agent 4 反序列化+RCE (D4+D5) 25 10
Agent 5 配置+加密+依赖 (D7+D8+D10) 25 11
R1 合计 125 turns 51 findings

Round 2(增量补漏 + 深度追踪)

Agent 方向 max_turns 新发现
R2-Agent 1 D4+D9(未覆盖维度) 20 4
R2-Agent 2 权限注解 AOP + SQL 查询构建层(浅覆盖加深) 20 5
R2-Agent 3 跨模块攻击链验证 20 3
R2 合计 60 turns 12 findings

7.3 关键发现一览

12 个 Critical 漏洞

---|---|---|---
C-01 | JWT 签名验证完全缺失 | 9.1 | JWT.decode()verify(),可伪造任意用户
C-02 | 权限注解无 AOP 实现 | 9.8 | 社区版鉴权函数永远返回 true
C-03 | 嵌入式数据库存储过程 RCE | 9.0 | JDBC URL 注入 → 执行任意 Java 代码
C-04 | SQL 查询构建层 9+ 注入点 | 8.8 | String.format() 拼接表名/字段名
C-05 | JDBC 连接参数反序列化 | 8.6 | 连接参数绕过黑名单触发反序列化

八、四个扫描模式

Skill 支持四种模式,适应不同场景:

模式 适用场景 轮次 Agent 数 特点
Quick CI/CD 集成、小项目 1 轮 2-3 高风险漏洞 + 密钥泄露 + 依赖 CVE
Quick-Diff PR 审查、增量提交 1 轮 1-2 只审计 git diff 变更的文件
Standard 常规安全审计 1-2 轮 3-9 OWASP Top 10 完整覆盖
Deep 关键系统、渗透测试前 2-4 轮 5-15 全量覆盖 + 攻击链 + 业务逻辑

九、模块化知识库

Skill 的知识不是全部写在一个文件里的。它采用模块化设计,按需加载:

核心模块(始终可用)

模块 功能
Anti-Hallucination 防幻觉规则和验证流程
Taint Analysis 污点分析和数据流追踪模板
PoC Generation 验证模板生成
Capability Baseline 防止能力退化的回归测试框架

十、置信度分级:Critical/High 必须有数据流

Skill 对发现的置信度有严格的分级标准:

等级 条件 可报告的最高严重度
已验证 完整数据流 + 无有效防护 + 可构造 PoC Critical
高置信 完整数据流 + 无有效防护,但 PoC 需特定环境 Critical/High
中置信 数据流不完整,或防护可绕过性不确定 Medium
需验证 仅 Grep 命中模式,未追踪数据流 Low/Info

十一、执行状态机:从侦察到报告的完整流转

整个审计过程由一个四状态执行状态机驱动:

PHASE_1_RECON  
    │ Phase 1 完成  
    ▼  
ROUND_N_RUNNING    ◄──────────────────────────┐  
    │ 所有 Agent 完成                          │  
    ▼                                         │  
ROUND_N_EVALUATION                           │  
    │                                         │  
    ├── 覆盖率不足 → NEXT_ROUND ─────────────►│  
    │  
    └── 覆盖率达标 + 弹性终止条件满足  
            │  
            ▼  
         REPORT

十二、Skill 迭代中踩过的坑

坑 1:Agent 输出被截断,发现全部丢失

早期没有截断防御机制,Agent 在最后一个 turn 还在做 Grep → 输出超长 → 被截断 → HEADER 和发现表格全部丢失 → 主线程拿到空结果。 修复 :Turn 预留规则 + HEADER 前置 + SENTINEL 哨兵 + 截断检测与恢复流程。

坑 2:R2 重复 R1 的工作

R2 Agent 不知道 R1 做了什么,重新搜索相同的模式、重读相同的文件。 修复 :跨轮传递结构(COVERED/GAPS/CLEAN/HOTSPOTS/FILES_READ/GREP_DONE)。

十三、与传统 SAST 工具的对比

维度 传统 SAST (Semgrep/SonarQube) code-audit Skill
检测方式 固定规则模式匹配 LLM 语义理解 + 数据流追踪
数据流追踪 有限(通常 1-2 跳) 深度(3+ 跳,含中间转换层)
业务逻辑漏洞 几乎无法检测 可检测(D9 维度)
误报率 较高(20-40%) 较低(防幻觉规则约束)
攻击链分析 支持多漏洞串联分析

十四、总结与展望

code-audit Skill 不是一个 prompt template,而是一个完整的审计系统。它的核心创新在于:

  1. 防幻觉优先 — 宁可漏报不可误报,每个发现必须有代码证据
  2. 覆盖率驱动 — 10 维度矩阵确保不遗漏任何安全方向
  3. 增量补漏 — R2 只补缺口不重复,Token 效率提升 40%+
  4. Agent 合约 — 结构化约束让多智能体行为可控可预测
  5. 截断防御 — HEADER 前置 + 哨兵机制确保关键数据不丢失
  6. 攻击链思维 — 不只找单点漏洞,还分析多漏洞组合的端到端攻击路径

文章来源: https://www.freebuf.com/articles/470778.html
如有侵权请联系:admin#unsafe.sh