SKILL.md
name: java-audit-skill description: | AI驱动的Java/前端代码安全审计技能,实现系统化、高覆盖率的漏洞挖掘。使用场景: (1) 审计Java/Kotlin项目寻找安全漏洞(0day挖掘、代码审计、安全评估) (2) 审计前端项目(JavaScript/TypeScript/React/Vue)寻找安全漏洞 (3) 企业级代码库的安全审计(支持大型项目) (4) 需要高质量、低幻觉率的安全审计报告 (5) CI/CD集成的前期漏洞发现 触发关键词:Java审计、代码审计、安全审计、漏洞挖掘、0day、安全评估、前端审计、React审计、Vue审计、Java security audit、code review for security
AI+Java/前端 代码审计 Skill
本 Skill 将资深审计员的工作方法和质量标准编码成 LLM 可执行的协议,解决裸跑 LLM 覆盖率低、幻觉高、优先级混乱等核心痛点。
支持的语言类型
| 语言类型 | 框架支持 | 主要检查内容 |
|---|---|---|
| Java/Kotlin | Spring、Spring Boot、Struts、Jersey、Dubbo、gRPC | 反序列化、SQL注入、命令执行、认证绕过、SSRF、文件操作 |
| JavaScript/TypeScript | 原生、Node.js | XSS、代码注入、原型污染、敏感信息泄露 |
| React | React 16+、Next.js | dangerouslySetInnerHTML、href注入、SSR XSS |
| Vue | Vue 2/3、Nuxt.js | v-html XSS、模板注入、不安全渲染 |
| 混合项目 | 前后端分离 | 后端API安全 + 前端XSS/配置安全 |
脚本架构
⚠️ 重要:脚本已按语言类型拆分,职责清晰
scripts/
├── audit.py # 通用入口(语言检测 + 路由分发)
├── java_audit.py # Java/Kotlin 后端审计
└── frontend_audit.py # JavaScript/React/Vue 前端审计
脚本职责
| 脚本 | 职责 | 包含功能 |
|---|---|---|
| audit.py | 通用入口 | 语言检测、路由分发、统一参数解析 |
| java_audit.py | Java 审计 | Java Tier 分类、Java 危险模式、EALOC 计算、覆盖率检查 |
| frontend_audit.py | 前端审计 | 前端 Tier 分类、前端危险模式、依赖检查、配置安全 |
调用流程
用户执行: python audit.py /path/to/project --scan --tier
↓
[audit.py]
↓
语言检测: detect_project_language()
↓
┌───────────────┼───────────────┐
│ │ │
java react/vue mixed
│ │ │
↓ ↓ ↓
[java_audit.py] [frontend_audit.py] [两者都执行]
使用方法
# 自动检测语言并执行审计
python scripts/audit.py /path/to/project --scan --tier
# Java 项目审计(直接调用)
python scripts/java_audit.py /path/to/java-project --scan --tier
# 前端项目审计(直接调用)
python scripts/frontend_audit.py /path/to/frontend-project --language react --scan --tier
核心理念
LLM 有能力,缺纪律。 Skill 不教 LLM "什么是 SQL 注入",而是给它装上资深审计员的工作骨架——定义工作流、分配资源、设置护栏、标准化输出。
6 阶段审计流水线
Phase 0 → Phase 1 → Phase 2 → Phase 2.5 → Phase 3 → Phase 5 → Phase 4(可选)
代码度量 项目侦察 多层审计 覆盖率门禁 漏洞验证 标准化报告 规则沉淀
每个 Phase 有明确的输入、输出和质量标准,中间结果全量持久化到文件。
⚠️ Phase 编号说明:
- Phase 0-3:核心审计流程(必须执行)
- Phase 5:标准化报告(在验证后生成)
- Phase 4:规则沉淀(可选,在报告后执行)
Phase 4 放在最后的原因:规则沉淀基于最终确认的漏洞(Phase 3 输出),且需要完整的报告(Phase 5 输出)作为参考。
Phase 0: 代码库度量
目标: 统计项目规模,计算审计工作量,为 Agent 分配提供依据。
语言检测(新增)
⚠️ 在开始审计前,必须先检测项目语言类型:
# 执行语言检测
python scripts/java_audit.py /path/to/project --detect-lang
检测结果决定审计流程:
| 语言类型 | 审计流程 | Semgrep 规则集 |
|---|---|---|
| java | Java 后端审计流程 | java-rce.yaml, java-config.yaml, java-sqli.yaml |
| javascript | 前端通用审计流程 | js-security.yaml, frontend-config.yaml |
| react | React 审计流程 | react-security.yaml, js-security.yaml |
| vue | Vue 审计流程 | vue-security.yaml, js-security.yaml |
| mixed | 前后端分离审计流程 | Java 规则 + 前端规则 |
语言检测逻辑:
1. 统计文件扩展名:
- .java/.kt → Java/Kotlin
- .js/.ts/.jsx/.tsx/.vue → 前端
2. 检测框架特征:
- pom.xml/build.gradle → Java 项目
- package.json → 前端项目
- react/vue 依赖 → React/Vue 项目
3. 判断项目类型:
- 纯 Java/Kotlin → java
- 纯前端 → javascript/react/vue
- 前后端分离 → mixed
执行脚本
Linux/macOS (Bash):
# 统计代码行数和文件数(注意括号)
find . \( -name "*.java" -o -name "*.kt" -o -name "*.xml" \) | xargs wc -l | tail -1
# 统计各类型文件
find . -name "*.java" | wc -l
find . -name "*.kt" | wc -l
find . -name "*.xml" | wc -l
# 统计 Controller/入口点数量(多种框架)
# 入口点定义详见 Phase 1 Tier 分类规则 Rule 2
# Spring MVC
grep -r "@Controller\|@RestController" --include="*.java" | wc -l
# 原生 Servlet
grep -r "@WebServlet\|extends HttpServlet\|implements Servlet" --include="*.java" | wc -l
# Struts Action
grep -r "extends ActionSupport\|implements Action\|@Action" --include="*.java" | wc -l
# Filter(也是 T1 级文件)
grep -r "@WebFilter\|implements Filter\|extends OncePerRequestFilter" --include="*.java" | wc -l
# 统计模块数(Maven 多模块项目)
find . -name "pom.xml" | wc -l
# 统计模块数(Gradle 多模块项目)
find . -name "build.gradle" -o -name "build.gradle.kts" | wc -l
Windows (PowerShell):
# 统计代码行数和文件数
Get-ChildItem -Recurse -Include *.java,*.kt,*.xml | Measure-Object -Property Length -Sum
# 统计各类型文件数
(Get-ChildItem -Recurse -Filter *.java).Count
(Get-ChildItem -Recurse -Filter *.kt).Count
(Get-ChildItem -Recurse -Filter *.xml).Count
# 统计 Controller/入口点数量(多种框架)
# Spring MVC
Select-String -Path (Get-ChildItem -Recurse -Filter *.java).FullName -Pattern "@Controller|@RestController" | Measure-Object | Select-Object -ExpandProperty Count
# 原生 Servlet
Select-String -Path (Get-ChildItem -Recurse -Filter *.java).FullName -Pattern "@WebServlet|extends HttpServlet|implements Servlet" | Measure-Object | Select-Object -ExpandProperty Count
# Struts Action
Select-String -Path (Get-ChildItem -Recurse -Filter *.java).FullName -Pattern "extends ActionSupport|implements Action|@Action" | Measure-Object | Select-Object -ExpandProperty Count
# Filter(也是 T1 级文件)
Select-String -Path (Get-ChildItem -Recurse -Filter *.java).FullName -Pattern "@WebFilter|implements Filter|extends OncePerRequestFilter" | Measure-Object | Select-Object -ExpandProperty Count
# 统计模块数(Maven)
(Get-ChildItem -Recurse -Filter pom.xml).Count
# 统计模块数(Gradle)
(Get-ChildItem -Recurse -Include build.gradle,build.gradle.kts).Count
输出文件: audit-metrics.json
{
"total_loc": 131000,
"java_files": 847,
"kt_files": 0,
"xml_files": 156,
"controllers": 40,
"modules": 5,
"t1_loc": 14000,
"t2_loc": 30000,
"t3_loc": 87000,
"ealoc": 37700,
"project_size": "中型",
"coverage_requirement": "95%",
"build_system": "maven"
}
EALOC 计算
EALOC(Effective Audit Lines of Code)在 Phase 0 计算,用于判断项目规模和后续执行策略:
EALOC = T1_LOC × 1.0 + T2_LOC × 0.5 + T3_LOC × 0.1
| 项目规模 | EALOC | 覆盖率要求 | 执行策略 |
|---|---|---|---|
| 小型 | < 15,000 | 100% | 单会话完成,可简化流程 |
| 中型 | 15,000 - 50,000 | 95% | 按模块拆分 |
| 大型 | > 50,000 | 90% | 必须拆分多 Agent |
Tier 分类规则(用于 EALOC 计算):
| Tier | 文件类型 | 权重 |
|---|---|---|
| T1 | Controller、Filter、Servlet、Action | × 1.0 |
| T2 | Service、DAO、Util、配置文件 | × 0.5 |
| T3 | Entity、VO、DTO | × 0.1 |
使用 Python 脚本可生成更多输出:
# 度量 + Tier 分类
python scripts/java_audit.py /path/to/project --tier
# 度量 + 场景标签(Phase 1)
python scripts/java_audit.py /path/to/project --scenario
# 度量 + Layer 1 预扫描
python scripts/java_audit.py /path/to/project --scan
可生成的输出文件:
audit-metrics.json- 项目度量数据tier-classification.md- Tier 分类报告(--tier)scenario-tags.json- API 场景标签(--scenario,Phase 1)p0-critical.md,p1-high.md,p2-medium.md- Layer 1 扫描报告(--scan)coverage-report.md- 覆盖率验证报告(--coverage)
Phase 1: 项目侦察 & EALOC 资源分配
1.1 业务场景标签
核心理念:不是所有 API 都需要深度审计。通过业务场景标签快速识别高风险 API,精准分配审计资源。
场景类型分类
| 场景类型 | 典型 API | 默认风险等级 | 重点检查 |
|---|---|---|---|
| FINANCIAL_TRANSACTION | 支付、退款、转账 | CRITICAL | 金额篡改、并发竞争、状态机绕过 |
| PRIVILEGED_OPERATION | 用户管理、系统配置 | HIGH | 垂直越权、权限绕过 |
| RESOURCE_ALLOCATION | 下单、抢购、预约 | HIGH | 并发竞争、库存绕过 |
| STATE_TRANSITION | 审批、发货、退款 | HIGH | 状态机绕过、流程跳跃 |
| DATA_ACCESS | 订单详情、用户列表 | MEDIUM | 水平越权、信息泄露 |
| USER_OPERATION | 个人资料、修改密码 | MEDIUM | 认证绕过、密码安全 |
| PUBLIC_ACCESS | 首页、公告、公开文章 | LOW | XSS、SSRF(可快速模式) |
自动识别脚本
Linux/macOS (Bash):
# 识别资金交易接口
grep -rn "pay\|payment\|refund\|transfer\|withdraw" --include="*.java" --include="*.kt" | grep -i "mapping"
# 识别特权操作接口
grep -rn "@PreAuthorize.*ADMIN\|@Secured.*ADMIN\|hasRole.*ADMIN" --include="*.java" --include="*.kt"
# 识别公开访问接口
grep -rn "permitAll\|anonymous" --include="*.java" --include="*.kt"
Windows (PowerShell):
# 识别资金交易接口
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "pay|payment|refund|transfer|withdraw" | Select-String -Pattern "mapping" -CaseSensitive:$false
# 识别特权操作接口
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "@PreAuthorize.*ADMIN|@Secured.*ADMIN|hasRole.*ADMIN"
# 识别公开访问接口
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "permitAll|anonymous"
详细说明: references/business-scenario-tags.md
1.2 Tier 分类规则
| 规则 | 条件 | Tier | 分析深度 |
|---|---|---|---|
| Rule 0 | 第三方库源码 | SKIP | 不审计 |
| Rule 1 | Layer 1 预扫描有 P0/P1 候选项 | T1 | 动态提升 |
| Rule 2 | 入口点类(详见下方) | T1 | 完整深度分析 |
| Rule 3 | 含 @Service/@Repository/@Mapper | T2 | 聚焦关键维度 |
| Rule 4 | 类名含 Util/Helper/Handler | T2 | 聚焦关键维度 |
| Rule 5 | .properties/.yml/security.xml | T2 | 聚焦关键维度 |
| Rule 6 | 含 @Entity/@Table/@Data | T3 | 快速模式匹配 |
| Rule 7 | 未匹配任何规则 | T2 | 保守兜底 |
Rule 2: 入口点类定义(T1 级文件)
入口点是接收外部 HTTP 请求的类,必须 100% 覆盖审计:
| 框架类型 | 入口点特征 | 示例 |
|---|---|---|
| Spring MVC | @Controller, @RestController | @RestController public class UserController |
| 原生 Servlet | @WebServlet, extends HttpServlet, implements Servlet | @WebServlet("/api/user") public class UserServlet |
| Struts 2 | extends ActionSupport, implements Action, @Action | public class UserAction extends ActionSupport |
| Filter | @WebFilter, implements Filter, extends OncePerRequestFilter | @WebFilter("/*") public class AuthFilter |
| Jersey/JAX-RS | @Path, @Provider | @Path("/users") public class UserResource |
| Play Framework | extends Controller, extends Action | public class UserController extends Controller |
扫描命令:
# Spring MVC
Select-String -Pattern "@Controller|@RestController"
# 原生 Servlet
Select-String -Pattern "@WebServlet|extends HttpServlet|implements Servlet"
# Struts 2
Select-String -Pattern "extends ActionSupport|implements Action|@Action"
# Filter
Select-String -Pattern "@WebFilter|implements Filter|extends OncePerRequestFilter"
# Jersey/JAX-RS
Select-String -Pattern "@Path|@Provider"
# 全部入口点
Select-String -Pattern "@Controller|@RestController|@WebServlet|extends HttpServlet|implements Servlet|extends ActionSupport|implements Action|@Action|@WebFilter|implements Filter|@Path"
1.3 EALOC 场景修正
基础 EALOC 计算:见 Phase 0(EALOC = T1_LOC × 1.0 + T2_LOC × 0.5 + T3_LOC × 0.1)
场景修正系数(用于高风险 API):
| 场景 | 修正系数 | 原因 |
|---|---|---|
| FINANCIAL_TRANSACTION(资金交易) | × 1.5 | 需要更深度审计 |
| PRIVILEGED_OPERATION(特权操作) | × 1.2 | 越权风险高 |
| RESOURCE_ALLOCATION(资源分配) | × 1.2 | 并发竞争风险 |
| STATE_TRANSITION(状态变更) | × 1.2 | 状态机绕过风险 |
| DATA_ACCESS(数据访问) | × 1.0 | 基准 |
| USER_OPERATION(用户操作) | × 1.0 | 基准 |
| PUBLIC_ACCESS(公开访问) | × 0.5 | 风险较低 |
修正后 EALOC:Adjusted_EALOC = Σ (API_EALOC × Scenario_Multiplier)
Agent 分配: Agent数量 = ceil(Adjusted_EALOC / 15000)
说明:此处的 "Agent" 为概念性描述,指审计任务拆分后的独立执行单元。实际执行时:
- 小型项目(EALOC < 15000):单会话完成,无需拆分
- 中型项目(EALOC 15000-50000):按模块拆分,可用
sessions_spawn启动子会话并行执行- 大型项目(EALOC > 50000):必须拆分,每个子任务独立输出
findings-raw.md,最后合并
1.4 依赖安全检查
执行时机:在 Phase 1 读取 pom.xml/build.gradle 时,同步检查依赖安全。
检查流程(mvnrepository.com 联网核实)
核心理念:不再依赖离线规则表,直接查询 Maven 仓库官方数据,获取准确的漏洞信息。
Step 1: 读取 pom.xml/build.gradle 提取依赖版本
↓
Step 2: 构建 mvnrepository.com 查询 URL
↓
Step 3: 使用 tavily + web_fetch 查询组件页面
↓
Step 4: 检查 "Direct vulnerabilities" 标记
↓
Step 5: 找到无漏洞的安全版本
mvnrepository.com 查询方法
URL 格式:
https://mvnrepository.com/artifact/{groupId}/{artifactId}
示例 URL:
https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
https://mvnrepository.com/artifact/com.alibaba/fastjson
https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
https://mvnrepository.com/artifact/org.apache.shiro/shiro-core
页面漏洞标记识别:
- 有漏洞版本:显示
Direct vulnerabilities: CVE-XXXX-XXXXX - 安全版本:无
Direct vulnerabilities标记
执行命令
方式一:tavily 搜索定位 + web_fetch 提取
# 1. tavily 搜索组件 mvnrepository 页面
node ~/.openclaw/workspace/skills/tavily-search/scripts/search.mjs "mvnrepository {groupId} {artifactId}" -n 5
# 2. web_fetch 提取页面内容
# 在 OpenClaw 中使用 web_fetch 工具访问组件页面
方式二:直接 web_fetch 组件页面
访问 https://mvnrepository.com/artifact/{groupId}/{artifactId}
在页面内容中搜索:
- "Direct vulnerabilities" → 存在漏洞
- 无此标记 → 安全版本
⚠️ CVE 核实铁律
- 禁止凭记忆编造 CVE 编号或安全版本 - 必须联网核实
- 必须使用 mvnrepository.com 官方数据 - 这是最准确的来源
- 必须检查 "Direct vulnerabilities" 标记 - 不是间接依赖漏洞
- 必须找到无漏洞的安全版本 - 在版本列表中寻找无标记的最新版本
检查示例:httpclient 4.5.12
Step 1: 访问 https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
Step 2: 检查版本列表:
- 4.5.12:
Direct vulnerabilities: CVE-2020-13956→ ❌ 有漏洞 - 4.5.13:
Direct vulnerabilities: CVE-2020-13956→ ❌ 有漏洞 - 4.5.14: 无标记 → ✅ 安全版本
结论: 当前版本 4.5.12 存在漏洞,建议升级到 4.5.14+
高优先级检查组件
以下组件历史上频繁出现高危漏洞,必须逐一检查:
| 组件 | groupId | artifactId | 检查 URL |
|---|---|---|---|
| Log4j2 | org.apache.logging.log4j | log4j-core | mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core |
| Fastjson | com.alibaba | fastjson | mvnrepository.com/artifact/com.alibaba/fastjson |
| Shiro | org.apache.shiro | shiro-core | mvnrepository.com/artifact/org.apache.shiro/shiro-core |
| Jackson | com.fasterxml.jackson.core | jackson-databind | mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind |
| HttpClient | org.apache.httpcomponents | httpclient | mvnrepository.com/artifact/org.apache.httpcomponents/httpclient |
| Netty | io.netty | netty-all | mvnrepository.com/artifact/io.netty/netty-all |
| Hessian | com.caucho | hessian | mvnrepository.com/artifact/com.caucho/hessian |
| XStream | com.thoughtworks.xstream | xstream | mvnrepository.com/artifact/com.thoughtworks.xstream/xstream |
| SnakeYAML | org.yaml | snakeyaml | mvnrepository.com/artifact/org.yaml/snakeyaml |
| Commons Collections | commons-collections | commons-collections | mvnrepository.com/artifact/commons-collections/commons-collections |
| Commons Text | org.apache.commons | commons-text | mvnrepository.com/artifact/org.apache.commons/commons-text |
| Nacos | com.alibaba.nacos | nacos-core | mvnrepository.com/artifact/com.alibaba.nacos/nacos-core |
| Dubbo | org.apache.dubbo | dubbo | mvnrepository.com/artifact/org.apache.dubbo/dubbo |
输出模板:dependency-security.md
## 依赖安全检查报告
**检查方法**:通过 mvnrepository.com 联网核实
**检查时间**:YYYY-MM-DD
| 组件 | groupId | artifactId | 当前版本 | Direct vulnerabilities | 安全版本 | 状态 |
|------|---------|------------|----------|------------------------|----------|------|
| httpclient | org.apache.httpcomponents | httpclient | 4.5.12 | CVE-2020-13956 | 4.5.14+ | ❌ 需升级 |
| log4j-core | org.apache.logging.log4j | log4j-core | 2.17.1 | 无 | - | ✅ 安全 |
| fastjson | com.alibaba | fastjson | 1.2.83 | 无 | - | ✅ 安全 |
### 详细检查记录
#### httpclient 4.5.12
- 检查 URL: https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
- 当前版本状态: Direct vulnerabilities: CVE-2020-13956
- 安全版本: 4.5.14(无 Direct vulnerabilities 标记)
- 建议: 升级到 4.5.14+
#### log4j-core 2.17.1
- 检查 URL: https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
- 当前版本状态: 无 Direct vulnerabilities
- 结论: 安全,无需升级
离线环境处理
无法联网时:
- 标记为
HYPOTHESIS:无法确认版本安全性 - 报告备注:注明"离线环境无法确认,建议联网后复查 mvnrepository.com"
- 保守评估:按"可能存在漏洞"处理,但不作为 CONFIRMED 漏洞
1.5 输出文件
tier-classification.md: Tier 分类结果scenario-tags.json: API 场景标签dependency-security.md: 依赖安全检查结果
tier-classification.md 示例
# Tier 分类结果
## 模块: module-biz (131,000 LOC)
| 子任务 | Agent | 文件范围 | 文件数 | Tier分布 | EALOC |
|--------|-------|---------|-------|---------|-------|
| 1a | Agent 1 | controller/ | 147 | T1: 14K | 14,000 |
| 1b | Agent 2 | service/ + dao/ | 200 | T2: 30K | 15,000 |
| 1c | Agent 3 | entity/ + vo/ | 500 | T3: 87K | 8,700 |
**总 EALOC**: 37,700 → 需要 3 个 Agent
Phase 2: 多层审计架构
Layer 1: 全量预扫描(不用 LLM)
使用 ripgrep + Semgrep 扫描所有文件,按 P0-P3 标记危险模式。
P0 级危险模式(RCE/反序列化)
Linux/macOS (Bash):
# 反序列化全家族(同时检查 Java 和 Kotlin 文件)
grep -rn "ObjectInputStream\|XMLDecoder\|XStream" --include="*.java" --include="*.kt"
grep -rn "JSON\.parseObject\|JSON\.parse\|@type" --include="*.java" --include="*.kt" # Fastjson
grep -rn "enableDefaultTyping\|activateDefaultTyping" --include="*.java" --include="*.kt" # Jackson
grep -rn "HessianInput\|Hessian2Input" --include="*.java" --include="*.kt" # Hessian
grep -rn "Yaml\(\)\.load\|Yaml\(\)\.loadAll\|new Yaml" --include="*.java" --include="*.kt" # SnakeYAML
grep -rn "Kryo\|Kryo\.readObject\|FSTObjectInput" --include="*.java" --include="*.kt" # Kryo/FST
# SSTI 全引擎
grep -rn "Velocity\.evaluate\|VelocityEngine\|mergeTemplate" --include="*.java" --include="*.kt"
grep -rn "freemarker\.template\|Template\.process\|FreeMarkerConfigurer" --include="*.java" --include="*.kt"
grep -rn "SpringTemplateEngine\|TemplateEngine\.process" --include="*.java" --include="*.kt" # Thymeleaf
# 表达式注入
grep -rn "SpelExpressionParser\|parseExpression\|evaluateExpression" --include="*.java" --include="*.kt"
grep -rn "OgnlUtil\|Ognl\.getValue\|ActionContext" --include="*.java" --include="*.kt"
# JNDI 注入
grep -rn "InitialContext\.lookup\|JdbcRowSetImpl\|setDataSourceName" --include="*.java" --include="*.kt"
# 命令执行
grep -rn "Runtime\.getRuntime\|ProcessBuilder\|exec(" --include="*.java" --include="*.kt"
# 脚本引擎代码执行
grep -rn "ScriptEngine\.eval\|ScriptEngineManager\|NashornScriptEngine" --include="*.java" --include="*.kt"
# 动态类加载(配合反射可 RCE)
grep -rn "Class\.forName\|ClassLoader\.loadClass\|URLClassLoader" --include="*.java" --include="*.kt"
grep -rn "getMethod\|invoke\|newInstance" --include="*.java" --include="*.kt" # 反射调用
Windows (PowerShell):
# 反序列化全家族(同时检查 Java 和 Kotlin 文件)
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "ObjectInputStream|XMLDecoder|XStream"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "JSON\.parseObject|JSON\.parse|@type" # Fastjson
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "enableDefaultTyping|activateDefaultTyping" # Jackson
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "HessianInput|Hessian2Input" # Hessian
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "Yaml\.load|new Yaml" # SnakeYAML
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "Kryo|FSTObjectInput" # Kryo/FST
# SSTI 全引擎
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "Velocity\.evaluate|VelocityEngine|mergeTemplate"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "freemarker\.template|Template\.process|FreeMarkerConfigurer"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "SpringTemplateEngine|TemplateEngine\.process" # Thymeleaf
# 表达式注入
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "SpelExpressionParser|parseExpression|evaluateExpression"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "OgnlUtil|Ognl\.getValue|ActionContext"
# JNDI 注入
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "InitialContext\.lookup|JdbcRowSetImpl|setDataSourceName"
# 命令执行
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "Runtime\.getRuntime|ProcessBuilder|exec\("
# 脚本引擎代码执行
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "ScriptEngine\.eval|ScriptEngineManager|NashornScriptEngine"
# 动态类加载(配合反射可 RCE)
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "Class\.forName|ClassLoader\.loadClass|URLClassLoader"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "getMethod|invoke|newInstance" # 反射调用
P1 级危险模式(SQL 注入/SSRF/文件操作/XXE/LDAP)
Linux/macOS (Bash):
# SQL 注入风险
grep -rn "Statement\|createStatement\|executeQuery\|executeUpdate" --include="*.java" --include="*.kt"
grep -rn '\$\{' --include="*.xml" # MyBatis ${} 注入
grep -rn "createQuery\|createNativeQuery" --include="*.java" --include="*.kt" # JPA/HQL 注入
# SSRF
grep -rn "URL\(|HttpURLConnection\|HttpClient\|RestTemplate\|WebClient" --include="*.java" --include="*.kt"
# 文件操作
grep -rn "FileInputStream\|FileOutputStream\|FileWriter\|Files\.read\|Files\.write" --include="*.java" --include="*.kt"
grep -rn "getOriginalFilename\|transferTo\|MultipartFile" --include="*.java" --include="*.kt" # 文件上传
grep -rn "\.\./\|getAbsolutePath" --include="*.java" --include="*.kt" # 路径穿越
# XXE(XML 外部实体)
grep -rn "DocumentBuilder\|SAXParser\|XMLReader\|SAXReader" --include="*.java" --include="*.kt"
grep -rn "setFeature.*external.*false\|setExpandEntityReferences.*false" --include="*.java" --include="*.kt" # XXE 防护检查
# LDAP 注入
grep -rn "SearchControls\|DirContext\.search\|ldapsearch" --include="*.java" --include="*.kt"
# 开放重定向
grep -rn "sendRedirect\|Response\.sendRedirect" --include="*.java" --include="*.kt"
# 日志注入
grep -rn "log\.info\|log\.debug\|log\.error" --include="*.java" --include="*.kt" | grep -i "request\|param\|input" # 日志记录用户输入
Windows (PowerShell):
# SQL 注入风险
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "Statement|createStatement|executeQuery|executeUpdate"
Get-ChildItem -Recurse -Include *.xml | Select-String -Pattern '\$\{' # MyBatis ${} 注入
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "createQuery|createNativeQuery" # JPA/HQL 注入
# SSRF
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "URL\(|HttpURLConnection|HttpClient|RestTemplate|WebClient"
# 文件操作
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "FileInputStream|FileOutputStream|FileWriter|Files\.read|Files\.write"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "getOriginalFilename|transferTo|MultipartFile" # 文件上传
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "\.\./|getAbsolutePath" # 路径穿越
# XXE(XML 外部实体)
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "DocumentBuilder|SAXParser|XMLReader|SAXReader"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "setFeature.*external|setExpandEntityReferences" # XXE 防护检查
# LDAP 注入
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "SearchControls|DirContext\.search|ldapsearch"
# 开放重定向
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "sendRedirect|Response\.sendRedirect"
# 日志注入
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "log\.info|log\.debug|log\.error"
P2 级危险模式(认证/授权/加密/敏感信息)
Linux/macOS (Bash):
# 认证相关
grep -rn "@PreAuthorize\|@Secured\|@RolesAllowed\|hasRole\|hasAuthority" --include="*.java" --include="*.kt"
grep -rn "permitAll\|anonymous\|authenticated" --include="*.java" --include="*.kt"
# 加密相关
grep -rn "MessageDigest\|Cipher\|SecretKey\|PasswordEncoder" --include="*.java" --include="*.kt"
grep -rn "MD5\|SHA1\|DES\|AES/ECB" --include="*.java" --include="*.kt" # 弱加密算法
# 不安全随机数
grep -rn "new Random\(\)\|Math\.random\(\)" --include="*.java" --include="*.kt"
# 硬编码敏感信息
grep -rn "password\s*=\s*\"\|secret\s*=\s*\"\|apiKey\s*=\s*\"" --include="*.java" --include="*.kt"
grep -rn "jdbc:mysql://\|jdbc:oracle:" --include="*.java" --include="*.kt" # 数据库连接字符串
# @InitBinder 配置检查
grep -rn "@InitBinder\|setDisallowedFields" --include="*.java" --include="*.kt" # Spring 参数绑定配置
Windows (PowerShell):
# 认证相关
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "@PreAuthorize|@Secured|@RolesAllowed|hasRole|hasAuthority"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "permitAll|anonymous|authenticated"
# 加密相关
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "MessageDigest|Cipher|SecretKey|PasswordEncoder"
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "MD5|SHA1|DES|AES/ECB" # 弱加密算法
# 不安全随机数
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "new Random\(\)|Math\.random\(\)"
# 硬编码敏感信息
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "password\s*=\s*\"|secret\s*=\s*\"|apiKey\s*=\s*\""
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "jdbc:mysql://|jdbc:oracle:" # 数据库连接字符串
# @InitBinder 配置检查
Get-ChildItem -Recurse -Include *.java,*.kt | Select-String -Pattern "@InitBinder|setDisallowedFields" # Spring 参数绑定配置
⚠️ @InitBinder 分析指南(重要)
当发现 @InitBinder 或 setDisallowedFields 时,必须按以下步骤验证:
Step 1:验证类继承关系
# 检查 Controller 是否继承了父类
Select-String -Path $controllerFile -Pattern "class.*Controller.*extends|class.*Controller\s*\{"
| 情况 | 结论 |
|---|---|
继承父类 + 有自己的 @InitBinder |
可能是"覆盖" |
未继承父类 + 有自己的 @InitBinder |
不是"覆盖",是"新增配置" |
Step 2:验证参数绑定方式
# 检查接口参数注解
Select-String -Path $controllerFile -Pattern "@RequestBody|@ModelAttribute|@RequestParam|public.*\("
| 参数注解 | 受 @InitBinder 影响 | 分析重点 |
|---|---|---|
@RequestBody |
❌ 否(JSON 反序列化) | 检查 DTO 字段 |
@ModelAttribute |
✅ 是 | 高风险,需详细分析 |
| 无注解(对象参数) | ✅ 是 | 高风险,需详细分析 |
@RequestParam |
⚠️ 部分(单个字段) | 低风险 |
Step 3:验证业务场景
# 检查是否涉及用户管理
Select-String -Path $files -Pattern "UserService|UserRepository|isAdmin|role|permission"
Step 4:验证 DTO 字段
# 读取 DTO 类定义,检查字段
Get-Content $dtoFile
正确结论格式:
在 XxxController 中存在危险的 @InitBinder 配置:`binder.setDisallowedFields(new String[]{})`。
当前该控制器有 X 个接口,其中 Y 个使用表单参数绑定(受影响),Z 个使用 @RequestBody(不受影响)。
受影响的接口 DTO 只含 [字段列表],无敏感字段。
若后续新增参数绑定接口,可能存在批量分配风险。
错误案例(2026-04-01):
错误:报告"批量分配防护被覆盖",但 Controller 未继承父类,且全部使用 @RequestBody。 教训:未验证继承关系、参数绑定方式、业务场景、攻击路径。
Layer 2: 双轨审计模型
每个 Agent 执行两条并行的审计轨道:
轨道 1: Sink-driven(从危险代码往上追)
发现 Runtime.exec(cmd) → 追踪 cmd 参数来源 → 检查是否有过滤 → 判断是否来自用户输入
轨道 2: Control-driven(从端点往下查安全控制)
发现 /api/admin/deleteUser 端点 → 检查是否有认证注解 → 检查是否有权限校验
为什么需要两条轨道? 认证绕过这类漏洞,单独用 Sink-driven 找不到——该漏洞不是某行代码有问题,而是某个端点缺少了应有的权限检查。
Layer 2 执行流程
Step 1: 执行轨道 1 (Sink-driven)
↓ 对 L1 发现的危险 Sink 追踪参数来源
↓ 判断是否用户可控
↓ 输出普通漏洞候选列表
Step 2: 执行轨道 2 (Control-driven)
↓ 列出所有 Controller 入口
↓ 检查权限控制
↓ 输出越权/认证绕过候选列表
Step 3: 执行 Layer 2.5(仅对逻辑漏洞)
↓ 对资金交易、状态变更等敏感接口
↓ 执行 CoT 四步推理
↓ 输出逻辑漏洞候选列表
Layer 2.5: 逻辑漏洞 CoT 四步推理
执行时机:当发现以下场景时,必须执行 Layer 2.5:
| 场景 | 触发条件 | 示例 |
|---|---|---|
| 资金交易 | 涉及支付、退款、转账 | pay(), refund(), transfer() |
| 状态变更 | 涉及订单状态、审批流程 | updateStatus(), approve() |
| 资源分配 | 涉及库存、名额 | createOrder(), book() |
| 数据访问 | 涉及敏感数据查询 | getUserInfo(), getOrderDetail() |
⚠️ Layer 2.5 触发条件检查清单:
在执行 Layer 2 之前,必须先检查是否需要触发 Layer 2.5:
□ API 路径包含 pay/payment/refund/transfer/withdraw?
□ 方法名包含 updateStatus/approve/reject/confirm/cancel?
□ 涉及金额、价格、库存、数量字段?
□ 涉及状态机流转(订单状态、审批状态)?
□ 涉及用户间数据隔离(水平越权风险)?
□ 涉及特权操作(管理员功能、系统配置)?
→ 任一为是 → 必须执行 Layer 2.5
→ 全部为否 → 可跳过 Layer 2.5
注意:Layer 2.5 专门用于逻辑漏洞分析,普通漏洞(SQL注入、命令注入等)用 Layer 2 双轨审计即可。
对于 Semgrep 规则无法覆盖的漏洞类型,需要通过代码分析进行判断。
逻辑漏洞 CoT 四步推理
核心理念:逻辑漏洞的本质是"合法的代码执行了非预期的业务流程",需要强制 AI 像安全专家一样进行攻防推演。
Step 1: 场景与入口识别 → 识别 API 功能场景,分析用户可控参数
Step 2: 防御机制审计 → 寻找代码中的"锁"和"盾",分析完备性
Step 3: 对抗性沙箱模拟 → AI 设计 PoC,模拟真实链路处理
Step 4: 漏洞结果判定 → 基于推演给出负责任结论
Step 1: 场景与入口识别
识别内容:
1. API 功能场景(资金交易/数据访问/状态变更等)
2. 用户可控参数列表
3. 参数风险标签:
- ID 类(userId, orderId)→ 数据定位,可能越权
- 金额类(amount, price)→ 资金相关,可能篡改
- 状态类(status, state)→ 状态控制,可能绕过状态机
- 数量类(count, quantity)→ 资源相关,可能并发问题
Step 2: 防御机制审计
寻找代码中的"锁"和"盾":
| 锁类型 | 代码特征 | 检查点 |
|---|---|---|
| 权限锁 | @PreAuthorize, hasRole() |
是否存在?是否完整? |
| 归属锁 | userId.equals(currentUser.getId()) |
数据是否校验归属? |
| 状态锁 | if (order.getStatus() == PAID) |
状态前置条件是否完整? |
| 金额锁 | amount.equals(order.getAmount()) |
金额是否后端校验? |
| 并发锁 | synchronized, SELECT FOR UPDATE |
是否有并发控制? |
Step 3: 对抗性沙箱模拟
基于业务语义生成对抗性测试用例:
| 参数类型 | 测试值 | 目标漏洞 |
|---|---|---|
| 金额 | 负数、0、极大值 | 0元支付、负金额退款 |
| 数量 | 负数、超库存上限 | 库存为负、超量下单 |
| 状态 | 跳跃状态值 | 状态机绕过 |
| ID | 他人 ID | 水平越权 |
Step 4: 漏洞结果判定
- CONFIRMED: PoC 可执行,调用链完整,影响明确
- HYPOTHESIS: 发现可疑模式但无法完全确认,需人工验证
详细推理模板: references/logic-vulnerability-cot.md
业务逻辑漏洞检查要点
支付金额检查:
1. 金额是否来自前端?是否有后端校验?
2. 价格是否可被篡改?
3. 是否有金额一致性校验?
库存并发检查:
1. 是否有并发控制(锁/原子操作)?
2. 检查和扣减是否原子操作?
状态机检查:
1. 状态流转规则是否明确?
2. 敏感操作是否校验前置状态?
3. 是否有非法状态跳转?
越权漏洞检查要点
水平越权检查:
1. 数据查询是否校验归属?
2. userId 是否从 Session 获取(不可伪造)?
3. UPDATE/DELETE 是否有 userId 条件?
垂直越权检查:
1. 管理接口是否有权限注解?
2. 前后端权限是否一致?
3. 是否有权限配置遗漏?
依赖安全检查
⚠️ 必须通过 mvnrepository.com 联网核实,不再使用离线规则表。
检查流程:
1. 读取 pom.xml/build.gradle 提取依赖版本
2. 构建 mvnrepository.com 查询 URL
3. 使用 tavily + web_fetch 查询组件页面
4. 检查当前版本的 "Direct vulnerabilities" 标记
5. 找到无漏洞的安全版本
mvnrepository.com 查询方法:
URL 格式: https://mvnrepository.com/artifact/{groupId}/{artifactId}
示例:
https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
https://mvnrepository.com/artifact/com.alibaba/fastjson
https://mvnrepository.com/artifact/org.apache.shiro/shiro-core
漏洞标记识别:
- 有漏洞版本:页面显示
Direct vulnerabilities: CVE-XXXX-XXXXX - 安全版本:无
Direct vulnerabilities标记
执行命令:
# 方式一:tavily 搜索定位
node ~/.openclaw/workspace/skills/tavily-search/scripts/search.mjs "mvnrepository {groupId} {artifactId}" -n 5
# 方式二:直接 web_fetch 组件页面
# 使用 OpenClaw 的 web_fetch 工具访问 mvnrepository.com 页面
检查示例:
发现依赖: httpclient 4.5.12
Step 1: 访问 mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
Step 2: 检查版本列表:
- 4.5.12: Direct vulnerabilities: CVE-2020-13956 → ❌ 有漏洞
- 4.5.14: 无标记 → ✅ 安全版本
结论: 需要升级到 4.5.14+
⚠️ 核实铁律:
- 禁止凭记忆编造安全版本 - 必须在 mvnrepository.com 上核实
- 必须检查 "Direct vulnerabilities" - 这是直接依赖漏洞,非间接依赖
- 必须找到无标记的安全版本 - 在版本列表中寻找无漏洞标记的最新版本
运行时配置
检查要点:
1. Session 超时、Cookie Secure/HttpOnly
2. Actuator 端点暴露
3. 数据库密码明文存储
4. 调试模式开启
详细判断方法见: references/vulnerability-conditions.md 第 16-19 节
Layer 3: 调用链语义级验证
优先使用 LSP 做语义级追踪:
候选 Sink (Statement.executeUpdate(sql))
↓ goToDefinition → 确认实际实现
↓ findReferences → 向上追踪所有调用者
↓ hover → 获取中间变量类型
↓ 重复 findReferences → 直到到达 Controller 入口或确认不可达
↓ 记录完整调用链,每一跳标注 文件:行号
LSP 不可用时退化到 Grep + Read 手动追踪。
Phase 2.5: 覆盖率门禁
这是反 LLM 天性的核心设计——LLM 倾向于跳过"看起来不重要"的代码,而漏洞恰恰喜欢藏在那些地方。
自动化覆盖率检查
使用 scripts/java_audit.py 自动检查覆盖率:
# Python 脚本(跨平台)
python scripts/java_audit.py /path/to/project --coverage --reviewed-file findings-raw.md
# 输出示例:
# [*] 覆盖率统计:
# 实际文件总数: 847
# 已审阅文件数: 820
# 遗漏文件数: 27
# 覆盖率: 96.8%
#
# [!] 门禁未通过 - 覆盖率 < 100%,需要补扫
门禁阈值
⚠️ 核心原则:T1 文件(Controller/Filter)必须 100% 覆盖,无例外。
| 项目规模 | EALOC | T1 覆盖率 | T2 覆盖率 | T3 覆盖率 | 总体覆盖率 |
|---|---|---|---|---|---|
| 小型项目 | < 15,000 | 100% | 95% | 90% | 100% |
| 中型项目 | 15,000 - 50,000 | 100% | 95% | 85% | 95% |
| 大型项目 | > 50,000 | 100% | 90% | 80% | 90% |
门禁判断逻辑:
门禁通过条件(必须全部满足):
1. T1 覆盖率 == 100%(硬性要求,无例外)
2. T2 覆盖率 >= 阈值(中型 95%,大型 90%)
3. T3 覆盖率 >= 阈值(中型 85%,大型 80%)
4. 总体覆盖率 >= 阈值(小型 100%,中型 95%,大型 90%)
说明:
- T1(Controller/Filter):入口点文件,安全风险最高,必须全部审计
- T2(Service/DAO):业务逻辑层,覆盖率要求较高
- T3(Entity/VO):数据模型层,覆盖率要求相对较低
模块覆盖矩阵
| # | 模块路径 | LOC | EALOC | Controller数 | 风险评估 | 分配 Agent | Phase2 状态 | Phase3 状态 |
|---|---------|-----|-------|-------------|---------|-----------|------------|------------|
| 1 | module-auth | 8,000 | 5,200 | 6 | HIGH | Agent 1 | 完成 | 完成 |
| 2 | module-gateway | 12,000 | 7,800 | 8 | HIGH | Agent 2 | 完成 | 进行中 |
| 3 | module-biz | 131,000 | 37,700 | 40 | HIGH | Agent 3a~3c | 部分完成 | 未开始 |
文件级覆盖率验证
每个 Agent 输出必须包含审阅文件清单:
| # | 文件路径 | Tier | 状态 | 发现数 |
|---|---------|------|------|-------|
| 1 | AuthController.java | T1 | 完成 已审阅 | 2 |
| 2 | ShiroConfig.java | T1 | 完成 已审阅 | 1 |
| 3 | UserServiceImpl.java | T2 | 完成 已审阅 | 0 |
| 4 | User.java | T3 | 完成 已审阅 | 0 |
| 5 | com/alibaba/fastjson/JSON.java | SKIP | 跳过 第三方库 | - |
门禁检查: 拿这份清单和 find 命令的实际文件列表做 diff。清单里没出现的文件 = 漏审。
门禁判断逻辑
收到每个 Agent 结果后立即执行:
1. 读取 Agent 输出的「审阅文件清单」
2. 与实际文件列表交叉验证
3. 覆盖率达到阈值 → 该 Agent 通过
覆盖率未达标 → 立即为未覆盖文件启动补扫 Agent
所有 Agent 完成后:
- 全部模块 Phase2 = 完成 → 进入 Phase 3
- 存在 未开始 或 部分完成 → 启动补充 Agent → 循环直到达标
覆盖率不达标处理流程
┌─────────────────────────────────────────────────────────────────┐
│ 覆盖率门禁回溯机制 │
└─────────────────────────────────────────────────────────────────┘
Phase 2.5: 检查覆盖率
┌─────────────────────────────────────┐
│ 计算覆盖率 = 已审阅文件 / 总文件数 │
└─────────────────────────────────────┘
↓
┌─────┴─────┐
│ 覆盖率达标?│
└─────┬─────┘
是 ↓ ↓ 否
┌──────────┐ ┌──────────────────────┐
│进入 │ │ 1. 列出遗漏文件列表 │
│Phase 3 │ │ 2. 返回 Phase 2 │
└──────────┘ │ 3. 补扫遗漏文件 │
│ 4. 更新审阅清单 │
│ 5. 再次检查覆盖率 │
└──────────┬───────────┘
↓
┌─────┴─────┐
│ 达标? │
└─────┬─────┘
是 ↓ ↓ 否
┌──────────┐ ┌──────────┐
│Phase 3 │ │ 循环补扫 │
└──────────┘ └──────────┘
补扫命令:
# 1. 获取遗漏文件列表
# 对比实际文件列表和已审阅清单
$allFiles = Get-ChildItem -Recurse -Filter *.java | Select-Object -ExpandProperty Name
$reviewedFiles = Get-Content findings-raw.md | Select-String -Pattern "\.java"
$missingFiles = Compare-Object $allFiles $reviewedFiles
# 2. 对遗漏文件执行审计
foreach ($file in $missingFiles) {
Read $file
# 执行 Layer 2 分析
}
# 3. 更新 findings-raw.md
# 4. 重新计算覆盖率
阈值说明:见上门禁阈值表,按项目规模分级执行。T1 文件必须 100% 覆盖。
质量校验自动化
每个阶段输出后,自动运行质量校验脚本检查输出质量。
校验脚本
# Linux/macOS
./scripts/quality-checker.sh <phase> <project_path>
# Windows PowerShell
.\scripts\quality-checker.ps1 -Phase <phase> -ProjectPath <project_path>
# 全量校验
./scripts/quality-checker.sh all /path/to/project
校验阶段与检查项
| 阶段 | 校验项 | 不通过条件 |
|---|---|---|
| phase1 | EALOC 计算 | 缺失 |
| phase1 | Tier 分类 | 缺失或 T1=0 |
| phase2-layer1 | 危险模式文件 | p0/p1/p2 全缺失 |
| phase2-layer2 | 精确行号 | 无 文件:行号 格式 |
| phase2-layer2 | 调用链分析 | 0 个调用链 |
| phase25 | 覆盖率 | 总体 < 90% |
| phase25 | T1 覆盖率 | < 100% |
| phase3 | CONFIRMED/HYPOTHESIS | 无状态标记 |
| phase3 | DKTSS 评分 | 缺失 |
| phase5 | 报告结构 | 缺少漏洞列表/审计进度 |
| phase5 | 完整路径 | 代码位置非绝对路径 |
| phase5 | 标题格式 | 包含严重程度标签 |
自动化流程
Phase 1 执行完成
↓ 自动运行
quality-checker.sh phase1 /project/path
↓
通过 → 继续执行 Phase 2
不通过 → 返回 Phase 1 补充
Phase 2 Layer 1 执行完成
↓ 自动运行
quality-checker.sh phase2-layer1 /project/path
↓
通过 → 继续执行 Layer 2
不通过 → 检查扫描命令
...以此类推...
校验示例
# Phase 5 报告校验
$ ./scripts/quality-checker.sh phase5 /path/to/project
[*] Phase 5 质量校验...
[✓] 「漏洞列表」部分存在
[✓] 「审计进度」部分存在
[✓] 代码位置格式正确(完整绝对路径)
[✓] 标题格式正确(无严重程度标签)
[✓] 调用链分析完整
[✓] 修复建议存在
[*] Phase 5 校验完成: 0 错误, 0 警告
Phase 3: 漏洞验证 & DKTSS 评分
⚠️ Phase 3 与 Layer 3 的区别
| 名称 | 所属阶段 | 作用 |
|---|---|---|
| Layer 3 | Phase 2 内部 | 调用链语义验证,用 Read 验证每一跳 |
| Phase 3 | 独立阶段 | 最终漏洞确认、反幻觉检查、DKTSS 评分 |
Phase 2 内部:
Layer 1 → Layer 2 → Layer 3(调用链验证)
↓
输出 findings-raw.md
Phase 3:
读取 findings-raw.md
→ 反幻觉铁律检查
→ CVE 联网核实
→ DKTSS 评分
→ 状态标记
↓
输出 findings-verified.md
反幻觉 7 条铁律
- 报告漏洞前必须用 Read 验证文件存在
- 代码片段必须来自实际 Read 输出,不得编造
- 调用链每一跳必须标注 文件:行号
- 不确定的发现标记为 HYPOTHESIS,不得标记为 CONFIRMED
- 宁可漏报,不可误报
- CVE 编号必须联网核实,禁止凭记忆编造
- 行号必须用 Read 验证,禁止模糊范围或猜测
CVE 核实铁律详解
❌ 错误做法:
报告 CVE-2020-1948 为 Hessian 漏洞
实际情况:CVE-2020-1948 是 Apache Dubbo 漏洞,与 Hessian 库无关
✅ 正确做法:
1. 使用 tavily 搜索 "<组件名> <版本号> CVE"
2. 从 NVD/Snyk 官方数据确认 CVE 真实性
3. 确认影响版本范围
4. 确认 CVE 影响的具体组件(artifact)
行号验证铁律详解
❌ 错误做法:
grep 搜索后直接使用 grep 输出的行号
报告模糊范围:HeaderModelUtils.java:18-35
✅ 正确做法:
1. grep 搜索定位关键代码
2. 使用 Read 工具读取文件,验证实际行号
3. 精确标注:HeaderModelUtils.java:35
4. 多段代码分开标注:HttpUtil.java:252-253, 321
行号验证示例:
# grep 搜索
Select-String -Path $file -Pattern "getLoginUserByStr" | ForEach-Object { "Line $($_.LineNumber)" }
# Read 验证(必须执行)
Read 文件,确认 grep 输出的行号与实际内容匹配
分析深度铁律
漏洞分析必须达到 L3 级别,禁止写成三点式(成因+攻击+影响),禁止片面分析。
必须包含以下所有要素:
- ✅ 具体方法名:精确到
ClassName.methodName() - ✅ 具体行为:方法具体做了什么
- ✅ 缺少的安全控制:什么保护措施没有(列表形式)
- ✅ 攻击路径:攻击者可以如何利用(步骤形式)
- ✅ 调用链追踪:从入口到漏洞点的完整路径
- ✅ 漏洞类型归纳:标准漏洞分类(CWE)
- ✅ 未使用的安全机制:项目中存在但未启用的安全配置
禁止片面分析:
❌ 片面分析(不可接受):
`CommonController.uploadFile()` 方法接收用户上传的文件,没有对文件类型进行校验,
攻击者可以上传恶意文件。
问题:
- 没有说明具体哪个方法有问题
- 没有调用链追踪
- 没有说明缺少哪些具体的安全控制
- 没有对比分析
- 没有攻击路径说明
✅ 全面分析(符合要求):
`CommonController.uploadFile()` 方法(CommonController.java:49)接收 MultipartFile 参数,
直接调用 `FileUtil.saveFile()` 保存到服务器。
**调用链追踪**:
Controller → Service → FileUtil
**缺少的安全控制**:
1. 文件类型校验:未检查 Content-Type 和文件扩展名
2. 文件内容校验:未检查文件魔数/文件头
3. 文件名处理:使用原始文件名,未重命名
**攻击路径**:
1. 攻击者构造恶意 JSP WebShell
2. 修改 Content-Type 为 image/jpeg 绕过前端校验
3. 上传到服务器可访问目录
4. 访问上传的文件执行任意命令
**归纳漏洞类型**:任意文件上传(CWE-434)
样例(必须参照此格式):
`HeaderModelUtils.getLoginUserByStr()` 方法仅对 Header 中的 Base64 编码数据进行解码,
然后直接反序列化为 LoginUserBo 对象。系统没有对用户信息进行任何签名验证或加密保护,
攻击者可以轻松伪造任意用户的登录信息。
控制器层(如 `FlightController.setFlightCityHistory()`)直接从请求头 `la517_loginUser`
获取用户信息,该信息未经服务器端验证就传递给服务层使用,形成**客户端信任漏洞**。
经审查 `pom.xml` 发现项目已引入 JWT 相关依赖(`jjwt`),但全局搜索显示实际并未使用。
`LogInterceptor` 拦截器仅用于日志追踪(requestId 生成),不包含任何认证逻辑。
漏洞成立条件判断
详见 references/vulnerability-conditions.md
示例 - Fastjson 反序列化判断流程:
发现 JSON.parseObject() / JSON.parse() 调用
↓
检查版本:
< 1.2.68 → 直接可利用
1.2.68-1.2.80 → 检查 classpath 是否有特定依赖(groovy/jython/aspectj/commons-io)
≥ 1.2.83 → 检查 safeMode 配置
DKTSS 评分体系
详见 references/dktss-scoring.md
核心公式:Score = Base - Friction + Weapon + Ver
- Base: 按漏洞类型和实际影响评分
- Friction: 实战阻力(访问路径/权限门槛/交互复杂度)
- Weapon: 武器化程度
- Ver: 版本因子
状态定义
| 状态 | 定义 | 要求 |
|---|---|---|
| CONFIRMED | 已验证可利用 | PoC 可执行,调用链完整,影响明确 |
| HYPOTHESIS | 疑似漏洞,需人工验证 | 发现可疑模式但无法完全确认 |
关键原则: 宁可标记为 HYPOTHESIS 让人工验证,也不要把不确定的发现标记为 CONFIRMED 污染报告可信度。
Phase 4: Semgrep 规则沉淀(可选)
目标:将确认的漏洞模式转换为 Semgrep 静态分析规则,可集成到 CI/CD 流水线。
Semgrep 安装
# macOS
brew install semgrep
# Linux
pip install semgrep
# Windows (通过 pip)
pip install semgrep
# 验证安装
semgrep --version
快速扫描:
# 扫描所有规则(含新增的新兴技术安全规则)
semgrep --config rules/semgrep/ /path/to/project
# 仅扫描 P0 级规则
semgrep --config rules/semgrep/java-rce.yaml /path/to/project
semgrep --config rules/semgrep/java-emerging.yaml /path/to/project
# 输出 JSON 格式
semgrep --config rules/semgrep/ --json /path/to/project > semgrep-results.json
规则列表:见 rules/semgrep/README.md,共 314 条规则覆盖:
- 传统漏洞:RCE、SQL注入、SSRF、文件操作、加密安全
- 新兴技术:LLM/AI 安全、GraphQL、Kotlin 特有漏洞、Java 21 新特性
- 微服务安全:Feign、Gateway、Dubbo、gRPC、NoSQL 注入
- 组件配置:Log4j2、Spring Security、Shiro、Fastjson、JWT 等
- 业务安全:并发安全、输入验证、敏感数据处理
执行条件
Phase 4 为可选步骤,在以下情况下执行:
- 发现了新的漏洞模式,现有 Semgrep 规则未覆盖
- 需要将漏洞检测集成到 CI/CD 流水线
- 项目需要长期的自动化安全检测
输出文件
| 文件 | 说明 |
|---|---|
custom-rules.yaml |
自定义 Semgrep 规则文件 |
semgrep-results.json |
规则测试结果 |
规则编写规范
rules:
- id: custom-vulnerability-id
patterns:
- pattern: 危险模式
- pattern-not: 安全模式(排除误报)
message: 规则描述,说明漏洞风险和修复建议
severity: ERROR # ERROR / WARNING / INFO
languages: [java]
metadata:
category: security
cwe: "CWE-XXX"
references:
- https://example.com/reference
示例规则
rules:
- id: velocity-ssti
patterns:
- pattern: Velocity.evaluate($CONTEXT, $WRITER, $NAME, $USER_INPUT)
- pattern-not: Velocity.evaluate($CONTEXT, $WRITER, $NAME, "...")
message: 检测到用户可控的 Velocity 模板输入,存在 SSTI 风险
severity: ERROR
languages: [java]
metadata:
category: security
cwe: "CWE-94"
规则测试
# 测试单个规则
semgrep --config custom-rules.yaml /path/to/test/code
# 验证规则语法
semgrep --validate --config custom-rules.yaml
跳过条件
以下情况可跳过 Phase 4:
- 所有发现的漏洞都已被现有 Semgrep 规则覆盖
- 不需要 CI/CD 集成
- 时间紧迫,优先完成报告
Phase 5: 标准化报告生成
⚠️ 必须先阅读模板
在生成报告之前,必须完整阅读 references/report-template.md。
报告格式以 report-template.md 为准,SKILL.md 不再重复定义格式细节。
报告整体结构
报告包含以下部分:
- 漏洞列表:包含漏洞的名字
- 审计进度:包含 L1-L3 审计的进度
- 详细漏洞报告:每个漏洞包含三部分
- 描述:漏洞归纳描述,100字左右
- 漏洞详情:代码位置、问题代码展示、漏洞分析(300字以上)
- 修复建议:完整的解决方案
报告格式规范
| 内容 | 标签 | 说明 |
|---|---|---|
| 漏洞名称 | h1 (#) |
单独一个大名称 |
| 描述 | h3 (###) |
漏洞归纳描述,100字左右 |
| 漏洞详情 | h3 (###) |
包含代码位置、代码展示、漏洞分析 |
| 修复建议 | h3 (###) |
完整解决方案 |
⚠️ 报告格式铁律
1. 代码位置必须使用完整绝对路径
❌ 错误:
**代码位置**:
CommonController.java:49-62
✅ 正确:
**代码位置**:
E:\工作代码\xx\xx\src\main\java\com\example\controller\CommonController.java:49-62
2. 漏洞分析必须详细完整(300字以上)
漏洞分析部分必须包含:
| 要素 | 说明 |
|---|---|
| 1. 调用链追踪 | 从入口到漏洞点的完整路径,每一跳标注 文件:行号 |
| 2. 缺少的安全控制 | 表格形式列出 |
| 3. 攻击路径 | 步骤形式(1、2、3...) |
| 4. 对比分析 | 与安全代码的差异 |
| 5. 未使用的安全机制 | 项目中存在但未启用 |
| 6. 漏洞类型归纳 | CWE 标准分类 |
详细示例见 report-template.md。
3. 禁止在标题中添加严重程度标签
❌ 错误:
# 任意文件上传漏洞(Critical)
✅ 正确:
# 任意文件上传漏洞
反幻觉铁律(再次强调)
- 报告漏洞前必须用 Read 验证文件存在
- 代码片段必须来自实际 Read 输出,不得编造
- 调用链每一跳必须标注 文件:行号
- 不确定的发现标记为 HYPOTHESIS,不得标记为 CONFIRMED
- 分析深度必须达到 L3 级别(见 report-template.md)
行号定位规范
- 必须使用实际验证的行号,禁止模糊范围
- 精确到方法起始行,多段代码分开标注
- 示例:
HttpUtil.java:252-253, 321而非HttpUtil.java:177-193
报告输出文件
findings-raw.md: Phase 2 发现的候选漏洞findings-verified.md: Phase 3 验证后的确认漏洞(最终数据源)audit-report.md: Phase 5 格式化的最终报告
AI 代码审计 6 大核心方法
1. 语义化规则匹配
传统工具的规则是"死"的——只能匹配固定参数名。AI 通过语义识别核心业务含义,适配任意命名规范。
示例:越权漏洞检测
- 传统规则:检查是否存在
user_id参数 - AI 语义规则:识别接口中所有代表用户身份标识的参数,校验该参数用于定位业务数据归属时,是否与当前登录用户的身份存在强制绑定
适用场景:未授权访问、通用越权、验证码绕过、密码重置漏洞
2. 基于因果推理的业务流程异常审计
AI 先构建业务的因果关系基准与状态机模型,明确每个业务操作的强制前置条件(因)与合法后置状态(果),再通过反事实推理验证。
示例:电商支付场景
- 强制前置条件:订单已创建且未支付、支付金额一致、回调凭证合法
- 合法后置状态:订单变为待发货、库存扣减、生成发货单
- 测试用例:跳过支付直接调用发货确认接口
适用场景:流程绕过、步骤颠倒、非法状态跳转
3. 权限与访问控制的逻辑一致性审计
构建完整的权限-资源绑定模型,执行三类校验:
| 校验类型 | 方法 | 覆盖漏洞 |
|---|---|---|
| 水平越权校验 | 用同角色不同用户凭证测试 | 访问他人私有数据 |
| 垂直越权校验 | 用低权限凭证测试高权限接口 | 权限提升 |
| 一致性校验 | 对比同类接口权限校验逻辑 | 部分遗漏校验 |
适用场景:水平/垂直越权、未授权访问、前后端权限不一致
4. 边界条件与异常分支的对抗性生成审计
基于参数的业务语义生成对抗性测试用例,而非随机字符串:
| 参数类型 | 测试值 | 目标漏洞 |
|---|---|---|
| 金额 | 负数、0、极大值、超2位小数 | 0元支付、负金额退款 |
| 数量 | 负数、超库存上限 | 库存为负、超量下单 |
| 时间 | 超期时间、早于当前时间 | 绕过有效期限制 |
白盒扫描重点:异常捕获分支是否存在"跳过权限校验"、"异常时返回成功"、"泄露敏感信息"
5. 多维度关联的漏洞链推理
将单个缺陷按业务场景、接口依赖、数据流转关系关联,自动识别可串联的漏洞点。
示例漏洞链:
/api/user/list未授权访问 → 获取全量用户手机号和 user_id/api/user/password/reset仅校验手机号和 user_id,无验证码
→ 串联形成完整攻击链,实现任意用户密码重置
6. 白盒场景的代码语义级逻辑缺陷审计
重点扫描高频逻辑缺陷场景:
- 权限校验缺失(仅校验登录,未校验数据归属)
- 业务逻辑错误(金额计算顺序、库存扣减顺序)
- 异常处理缺陷(捕获异常后直接返回成功)
- 接口设计缺陷(无幂等性、敏感操作无二次校验)
长上下文问题 5 层解决方案
层级 1: 源头治理(性价比最高,降低 60%+ 上下文)
必过滤内容:
- 注释、空行、纯日志打印代码
- 单元测试文件
- 第三方依赖库
- 构建配置文件
- 自动生成代码(protobuf、MyBatis Mapper)
可过滤低风险内容:
- 仅含 get/set 的纯数据实体类
- 无安全风险的工具方法
- 非核心统计报表代码
注意:过滤必须基于语义识别,不能误删权限校验、加密解密、输入过滤等核心安全代码。
层级 2: 三层递进式审计架构(核心方案)
| 层级 | 内容 | Token 控制 |
|---|---|---|
| 第一层:全局架构层 | 项目架构说明、模块划分、全局权限模型、核心拦截器规则、对外接口清单 | ≤ 8K |
| 第二层:模块级审计 | 按业务域拆分独立审计单元,输入模块代码+全局安全基线+依赖接口元数据 | 32K-64K |
| 第三层:跨模块验证 | 仅输入关联模块核心代码片段+调用链路元数据 | ≤ 64K |
层级 3: 结构化语义压缩(降低 70%+ Token)
将代码转化为结构化元数据:
函数名:updateOrder
输入参数:orderId(用户可控字符串)、orderStatus(整型枚举)
核心业务逻辑:根据 orderId 修改订单状态
安全特征:无订单归属用户校验,无操作权限校验
下游依赖:orderDao.update
风险标签:越权风险高
层级 4: RAG + 多轮对话(突破窗口物理限制)
- 构建代码知识库:按函数/类拆分,生成向量嵌入存入向量库
- 精准检索相关上下文:通过自然语言或风险特征检索相关代码片段
- 多轮对话增量审计:每轮处理一个细分目标,上一轮输出作为下一轮轻量上下文
层级 5: 增量审计机制(工程化落地)
与 Git/CI/CD 集成,仅审计本次提交变更的代码及相关调用链路,减少 90%+ 上下文量。
5 大落地误区
❌ 误区 1:简单按行数拆分代码
问题:破坏代码语义关联,导致跨文件调用链路无法理解,严重漏报
正确做法:按业务边界、依赖关系拆分,采用三层递进式架构
❌ 误区 2:过度依赖长窗口模型
问题:超过 128K token 后注意力严重衰减,且成本极高
正确做法:中等窗口 + 裁剪分块 + RAG,长窗口仅作跨模块验证辅助
❌ 误区 3:全量代码丢给 AI
问题:上下文溢出、无关信息干扰、误报率飙升、速度极慢
正确做法:完成无效信息过滤与风险分级,遵循"非必要不输入"
❌ 误区 4:完全抛弃传统工具
问题:大模型存在幻觉问题,无法被规则匹配弥补
正确做法:传统工具前置过滤 + AI 深度推理 + 传统工具后置验证
❌ 误区 5:只关注已知漏洞
问题:浪费 AI 核心能力——检测业务逻辑漏洞
正确做法:聚焦传统工具无法覆盖的逻辑缺陷、越权漏洞、流程绕过
参考文档
| 文档 | 内容 |
|---|---|
| vulnerability-conditions.md | 漏洞成立条件判断表(Fastjson、JNDI、SSTI 等) |
| dktss-scoring.md | DKTSS 评分体系详细说明 |
| cve-offline-lookup.md | 常见 CVE 离线速查表(Log4j、Fastjson、Spring、Shiro 等) |
| report-template.md | 标准化漏洞报告模板 |
| logic-vulnerability-cot.md | 逻辑漏洞 CoT 四步推理流程 |
| business-scenario-tags.md | 业务场景标签系统 |
| security-checklist.md | Java Web 应用安全审计检查清单 |
Semgrep 规则文件
| 文件 | 覆盖内容 | 规则数 |
|---|---|---|
| java-rce.yaml | 反序列化、SSTI、表达式注入、命令注入 | 21 |
| java-sqli.yaml | SQL 注入、MyBatis ${} 注入 | 12 |
| java-ssrf.yaml | SSRF 漏洞 | 8 |
| java-file.yaml | 文件操作漏洞 | 14 |
| java-crypto.yaml | 加密算法安全 | 8 |
| java-misc.yaml | XXE、XSS、认证授权等 | 56 |
| java-config.yaml | 组件配置安全(60+ 组件) | 95 |
| java-emerging.yaml | LLM/AI、GraphQL、Kotlin、Java 21、并发安全 | 14 |
总计 314 条规则
示例项目
| 目录 | 说明 |
|---|---|
| examples/vulnerable-springboot/ | 完整审计报告示例(含 4 个漏洞详细分析) |
执行检查清单
审计开始前
- 确认项目路径和技术栈(Java/Kotlin 版本、框架)
- 运行 Phase 0 度量脚本
- 完成项目侦察,生成 Tier 分类和 EALOC 计算
- 生成业务场景标签(scenario-tags.json)
审计过程中
- Layer 1 预扫描完成,P0-P3 标记到位
- 每个 Agent 双轨审计(Sink-driven + Control-driven)
- 逻辑漏洞执行 CoT 四步推理
- 实时更新覆盖矩阵
- 文件级覆盖率验证(清单 vs 实际文件 diff)
审计完成后
- 覆盖率门禁达标(小型 100% / 中型 95% / 大型 90%)
- 每个漏洞遵循反幻觉 7 条铁律
- CVE 编号已联网核实(禁止凭记忆编造)
- 行号已用 Read 验证(禁止模糊范围)
- 依赖安全检查使用 tavily(禁止 web_search)
- 逻辑漏洞有完整 CoT 推理记录
- DKTSS 评分完整
- 报告三段式格式齐全(描述 + 漏洞详情 + 修复建议)
- 分析达到 L4 级别(1500字以上,包含完整 7 要素)
- CONFIRMED vs HYPOTHESIS 状态正确
- 已阅读 references/report-template.md
注意事项
- 不要信任 LLM 的"记忆":所有中间结果都持久化到文件
- "没有发现也是有效结果":每个文件必须有"已审阅,无发现"或发现记录
- javax. 和 jakarta. 双命名空间**:Java EE → Jakarta EE 迁移历史,扫描规则必须同时匹配两个命名空间
- 大模块拆分追踪:EALOC > 15000 的模块必须拆分成多个子任务
大型项目增强:CPG 工具支持
对于 EALOC > 50000 的大型项目,推荐使用代码属性图(CPG)工具增强分析能力。
推荐工具:Joern
优势:
- 支持反编译伪代码分析(可用于 jar 包审计)
- 提供完整的代码属性图(AST + CFG + PDG)
- 支持复杂的跨文件调用链追踪
- 内置查询语言(Joern Query)进行自定义规则
集成方式:
# 安装 Joern
./joern --script audit.sc
# audit.sc 示例
importCode("path/to/project")
cpg.method.name("exec").callIn.l.foreach { call =>
println(s"Potential RCE: ${call.location}")
}
适用场景:
- 超大型项目(>50 万行)
- 需要跨模块调用链分析
- 反编译代码审计
与现有架构整合
Layer 0: Joern CPG 构建(大型项目可选)
↓
Layer 1: ripgrep + Semgrep 预扫描
↓
Layer 2: LLM 双轨审计
↓
Layer 2.5: CoT 四步推理(逻辑漏洞)
↓
Layer 3: LSP/Joern 语义级验证
输出文件清单
| 文件 | 生成阶段 | 说明 |
|---|---|---|
audit-metrics.json |
Phase 0 | 项目度量数据(文件数、行数、EALOC) |
tier-classification.md |
Phase 1 | Tier 分类结果 |
scenario-tags.json |
Phase 1 | API 场景标签 |
dependency-security.md |
Phase 1 | 依赖安全检查结果 |
p0-critical.md |
Phase 2 Layer 1 | P0 级危险模式(需 --scan 参数) |
p1-high.md |
Phase 2 Layer 1 | P1 级危险模式(需 --scan 参数) |
p2-medium.md |
Phase 2 Layer 1 | P2 级危险模式(需 --scan 参数) |
findings-raw.md |
Phase 2 | 候选漏洞列表(未验证) |
findings-verified.md |
Phase 3 | 验证后漏洞列表(已确认) |
audit-report.md |
Phase 5 | 最终审计报告 |
custom-rules.yaml |
Phase 4(可选) | 自定义 Semgrep 规则 |
说明:
- 标注"需
--scan参数"的文件需要执行python scripts/java_audit.py --scan才会生成 - Phase 4 的
custom-rules.yaml为可选输出,仅当需要将漏洞模式沉淀为规则时生成
⚠️ 输入长度限制应对策略(重要)
问题: LLM 存在输入长度限制(约 200KB),一次性加载过多内容会导致 Range of input length should be [1, 202745] 错误。
分阶段执行策略
⚠️ 必须遵循以下分阶段执行策略,避免输入长度超限:
┌─────────────────────────────────────────────────────────────┐
│ 分阶段执行策略 │
└─────────────────────────────────────────────────────────────┘
Step 1: 脚本执行(不直接读取文件)
├── python audit.py --detect-lang # 仅获取语言检测结果
├── python java_audit.py --scan --tier # 仅获取扫描摘要
└── 输出内容是精简的摘要信息(< 10KB)
Step 2: 针对性搜索(不全文件读取)
├── search_content "password|secret" # 只返回匹配行
├── search_content "Runtime.getRuntime"
└── 输出内容是匹配的关键行(< 5KB)
Step 3: 分段读取关键文件(限制行数)
├── read_file offset=50 limit=30 # 只读取 30 行
├── read_file offset=100 limit=50 # 分段读取
└── 每次读取限制在 50-100 行以内
Step 4: 分段生成报告(分段写入)
├── write_to_file 先写框架
├── replace_in_file 逐个添加漏洞
└── 避免一次性写入大量内容
内容量限制规则
| 操作类型 | 限制 | 说明 |
|---|---|---|
| 脚本执行输出 | < 10KB | 脚本输出是精简摘要,不会超限 |
| search_content 结果 | < 5KB | 只返回匹配行,使用 headLimit 限制 |
| read_file 单次读取 | < 100 行 | 使用 offset 和 limit 参数分段读取 |
| 单次响应总内容 | < 50KB | 控制单次响应中的总内容量 |
大型项目处理策略(EALOC > 10000)
⚠️ 当 EALOC > 10000 时,必须采用以下策略:
┌─────────────────────────────────────────────────────────────┐
│ 大型项目审计流程 │
└─────────────────────────────────────────────────────────────┘
Phase 0: 仅执行脚本
├── python audit.py --detect-lang
├── python java_audit.py --scan --tier
└── 不直接读取任何源文件
Phase 1: 根据扫描结果确定重点
├── 读取 p0-critical.md、p1-high.md(脚本生成的报告)
├── 确定需要深入分析的文件列表(< 10 个)
└── 不全量读取所有文件
Phase 2: 针对性分析关键文件
├── 只读取 P0/P1 级危险模式涉及的文件
├── 分段读取(每次 < 100 行)
└── 使用 search_content 搜索关键模式
Phase 3: 分段生成报告
├── 先写入报告框架
├── 逐个添加漏洞详情
└── 每次添加 1-2 个漏洞
禁止的操作
| 禁止操作 | 原因 | 正确做法 |
|---|---|---|
| ❌ 一次性读取整个文件 | 可能超过 200KB | ✅ 使用 offset/limit 分段读取 |
| ❌ 一次性读取多个大文件 | 累积超限 | ✅ 逐个读取,控制总量 |
| ❌ 不使用脚本直接读取源文件 | 内容量不可控 | ✅ 先执行脚本获取摘要 |
| ❌ 在单次响应中处理过多漏洞 | 报告内容超限 | ✅ 分多次响应处理 |
正确的审计流程示例
# 正确流程(避免超限)
## Step 1: 执行脚本获取摘要
→ python audit.py /path/to/project --detect-lang
→ 输出: 语言类型、文件数量(< 2KB)
## Step 2: 执行扫描获取危险模式
→ python java_audit.py /path/to/project --scan --tier
→ 输出: P0/P1/P2 发现数量、文件列表(< 10KB)
## Step 3: 读取扫描报告确定重点
→ read_file p0-critical.md(< 5KB)
→ read_file p1-high.md(< 5KB)
→ 确定需要深入分析的文件(< 10 个)
## Step 4: 针对性搜索关键模式
→ search_content "password|secret" --headLimit 20
→ search_content "Runtime.getRuntime" --headLimit 10
→ 输出: 匹配的关键行(< 5KB)
## Step 5: 分段读取关键文件
→ read_file Controller.java offset=50 limit=30
→ read_file Service.java offset=100 limit=50
→ 每次读取 < 100 行
## Step 6: 分段生成报告
→ write_to_file findings-raw.md(先写框架)
→ replace_in_file(添加漏洞 1)
→ replace_in_file(添加漏洞 2)
→ 分多次添加,避免一次性写入过多
小型项目简化流程
适用条件:EALOC < 15,000(小型项目)
简化执行策略
| 标准流程 | 简化流程 | 说明 |
|---|---|---|
| Phase 0 + Phase 1 分开执行 | 合并执行 | 一次性统计 + 读取 pom.xml |
| Phase 2 Layer 1/2/3 分开 | 合并执行 | 直接 Read 所有文件 |
| Phase 2.5 覆盖率检查 | 可跳过 | 小型项目必须 100% 覆盖 |
| Phase 3 + Phase 5 分开 | 合并执行 | 验证 + 报告一起生成 |
简化流程图
Step 1: 度量 + 侦察
↓
- 统计文件数、行数
- 计算 EALOC,判断项目规模
- 读取 pom.xml,检查依赖安全
- 列出所有 Controller 入口
Step 2: 全量代码审计
↓
- Read 所有 Java 文件
- 检查权限控制(Control-driven)
- 追踪危险模式(Sink-driven)
- 记录所有发现
Step 3: 验证 + 报告
↓
- 应用反幻觉铁律
- CVE 联网核实
- 生成 audit-report.md
- 报告末尾添加覆盖率统计
小型项目执行命令
# Step 1: 度量
$files = Get-ChildItem -Recurse -Filter *.java
$files.Count # 文件数
($files | Get-Content | Measure-Object -Line).Lines # 行数
# Step 2: 列出所有文件
$files | Select-Object -ExpandProperty FullName
# Step 3: 逐个读取审计
foreach ($file in $files) {
Read $file.FullName
# 检查权限控制、危险模式
}
# Step 4: 生成报告
# 按 report-template.md 格式书写
覆盖率统计模板
## 审计覆盖率统计
| 层级 | 扫描内容 | 覆盖数量 | 总数量 | 覆盖率 |
|------|----------|----------|--------|--------|
| Layer 1 | 危险模式预扫描 | 18 个文件 | 18 个 Java 文件 | 100% |
| Layer 2 | 双轨审计 | 11 个 Controller | 11 个 Controller | 100% |
| Layer 3 | 调用链验证 | 6 个漏洞 | 6 个候选漏洞 | 100% |
文档版本: v1.9.2
最后更新: 2026-04-03
版本历史
| 版本 | 日期 | 变更内容 |
|---|---|---|
| v1.9.2 | 2026-04-03 | 新增:前端审计支持(JS/React/Vue)、语言检测功能、前端 Semgrep 规则 |
| v1.9.1 | 2026-04-03 | 修复:Tier 分类扩展支持多框架、覆盖率正则修复、Jakarta EE 规则、Layer 2.5 触发条件检查清单 |
| v1.9.0 | 2026-04-02 | 依赖安全检查重构(mvnrepository.com 联网核实)、新增质量校验脚本 |
| v1.8.0 | 2026-04-01 | 重构报告格式:h1漏洞名称 + 漏洞列表 + 审计进度 + 三段式漏洞详情 |
| v1.7.0 | 2026-03-31 | 初始版本 |