Java Code Audit - Java 项目静态安全审计
使用方式
/java-code-audit <项目路径>
从 ARGUMENTS 解析项目路径。如果未提供,使用当前工作目录。
声明
此 skill 仅用于已授权的安全审计和研究。
自主执行规则
- 不要暂停询问用户
- 遇到错误记录后跳过,继续下一项
- 保持工具调用密度 — 每次响应尽量并行调用多个工具
- 不输出冗长中间过程 — 只输出简短进度标记
Phase 1: 项目侦察
1.1 识别构建工具
并行 Glob 搜索:
**/pom.xml→ Maven**/build.gradle或**/build.gradle.kts→ Gradle**/build.xml→ Ant
记录构建工具类型和所有构建文件路径。
1.2 解析项目结构
- Glob
**/src/main/java/**/*.java统计源码文件数 - Glob
**/src/main/resources/**统计资源文件 - Glob
**/*.xml定位 MyBatis mapper 等配置文件 - 识别多模块结构(多个 pom.xml / build.gradle)
1.3 提取依赖清单
Maven 项目:
- Read 根 pom.xml,提取
<properties>中的版本变量 - 提取
<dependencies>和<dependencyManagement>中所有groupId:artifactId:version - 如果 version 是
${variable}形式,从 properties 中解析实际版本 - 多模块项目:遍历所有子模块 pom.xml
Gradle 项目:
- Read build.gradle,提取
implementation/compile/api依赖声明 - 解析
ext或buildscript中的版本变量 - 检查
gradle.properties中的版本定义
1.4 识别框架
根据依赖清单识别:
spring-boot-starter-*→ Spring Boot(记录版本)mybatis*→ MyBatisshiro-*→ Apache Shirostruts2-*→ Struts2spring-cloud-*→ Spring Cloudspring-security-*→ Spring Securityfastjson*→ FastJSONdubbo*→ Dubbo
记录到内部变量,供后续 Phase 针对性扫描。
Phase 2: SCA 依赖审计
将 Phase 1 提取的依赖清单与以下已知高危组件逐一比对。
高危组件 CVE 清单
远程代码执行 (RCE)
| groupId:artifactId | 高危版本 | CVE | 说明 |
|---|---|---|---|
| org.apache.logging.log4j:log4j-core | < 2.17.1 | CVE-2021-44228, CVE-2021-45046, CVE-2021-45105, CVE-2021-44832 | JNDI 注入导致 RCE,Log4Shell |
| com.alibaba:fastjson | < 1.2.83 | CVE-2022-25845 | autoType 反序列化 RCE |
| com.alibaba:fastjson2 | < 2.0.26 | 多个 | autoType 绕过 |
| org.apache.struts:struts2-core | < 2.5.30 | CVE-2021-31805 | OGNL 注入 RCE |
| com.thoughtworks.xstream:xstream | < 1.4.19 | CVE-2021-39144 | 反序列化 RCE |
| org.yaml:snakeyaml | < 2.0 | CVE-2022-1471 | 不安全反序列化 RCE |
| org.springframework.cloud:spring-cloud-gateway | < 3.1.1 | CVE-2022-22947 | SpEL 注入 RCE |
| org.apache.commons:commons-collections4 | < 4.1 | CVE-2015-6420 | 反序列化 gadget chain |
| commons-collections:commons-collections | 3.0 - 3.2.1 | CVE-2015-6420 | 反序列化 gadget chain |
| org.springframework:spring-beans | 5.3.0 - 5.3.17 | CVE-2022-22965 | Spring4Shell RCE (JDK9+) |
| org.springframework:spring-webmvc | 5.3.0 - 5.3.17 | CVE-2022-22965 | Spring4Shell RCE |
| org.apache.dubbo:dubbo | < 3.0.7 | CVE-2021-43297 | Hessian 反序列化 RCE |
| cn.hutool:hutool-all | < 5.8.11 | 多个 | 反序列化漏洞 |
认证绕过 / 权限问题
| groupId:artifactId | 高危版本 | CVE | 说明 |
|---|---|---|---|
| org.apache.shiro:shiro-core | < 1.7.1 | CVE-2020-1957 | 路径穿越认证绕过 |
| org.apache.shiro:shiro-web | < 1.7.1 | CVE-2020-1957 | 同上 |
| org.springframework.security:spring-security-core | < 5.6.2 | CVE-2022-22978 | RegexRequestMatcher 绕过 |
其他高危
| groupId:artifactId | 高危版本 | CVE | 说明 |
|---|---|---|---|
| commons-io:commons-io | < 2.7 | CVE-2021-29425 | 路径穿越 |
| com.fasterxml.jackson.core:jackson-databind | < 2.13.2.1 | CVE-2020-36518 | 深度嵌套 DoS |
| org.apache.tomcat.embed:tomcat-embed-core | 多版本段 | 多个 | 请求走私、信息泄露 |
| com.alibaba:druid | 任何版本 | 配置问题 | 检查 /druid/ 监控页是否有密码保护 |
| mysql:mysql-connector-java | < 8.0.28 | CVE-2021-2471 | SSRF via allowLoadLocalInfile |
| org.apache.poi:poi | < 5.2.0 | CVE-2022-26336 | XXE |
匹配流程
- 对每个依赖,查找
groupId:artifactId是否命中上表 - 命中 → 比对版本是否在高危范围内
- 版本在高危范围 → 记录:组件、当前版本、CVE 编号、风险等级、说明、建议升级版本
- 版本未解析成功 → 记录为「需人工确认」并标注原因
- 未命中表中组件但名称含
log4j/fastjson/shiro/struts/xstream→ 也做二次检查
Druid 特殊检查
如果依赖中包含 com.alibaba:druid:
- Grep 搜索
stat-view-servlet或StatViewServlet - 检查是否配置了
loginUsername和loginPassword - 未配置 → 报告为中危:Druid 监控页未授权访问
Phase 3: SAST 源码审计
对 src/main/ 下的源码执行 12 类漏洞检测。每类采用两步法:
- Grep 快筛 — 定位可疑文件和行号
- Read 上下文 — 读取前后 30-50 行,判断是否存在有效防护
误报控制规则
src/test/中的发现 → 降级为 INFO,不计入漏洞统计- 注释中的代码(
//、/*开头的行)→ 忽略 - 有明确防护(预编译、白名单、过滤器等)→ 标记「已防护」不报
- 项目自身封装的安全工具类 → 如果被调用方使用了安全封装,不报
扫描路径
- Java 源码:
**/src/main/java/**/*.java - MyBatis XML:
**/src/main/resources/**/*Mapper*.xml、**/*mapper*.xml、**/*dao*.xml - 配置文件:
**/application*.yml、**/application*.properties、**/bootstrap*.yml - Spring Security / Shiro 配置:在 Java 和 XML 中同时搜索
规则 1: SQL 注入
Grep 模式:
- MyBatis XML:
\$\{(在 *.xml 文件中,排除${ew.、${page.等框架安全用法) - JDBC:
(Statement|Connection)\s*\..*\.(execute|addBatch)\s*\(+ 上下文有字符串拼接 - JPA:
nativeQuery\s*=\s*true+ 上下文有字符串拼接+ - StringBuffer/Builder 拼 SQL:
(append|concat)\s*\(.*("SELECT|"INSERT|"UPDATE|"DELETE|"WHERE)
判断是否漏洞:
- MyBatis
${}用于ORDER BY、GROUP BY、表名 → 常见但仍有风险,标记中危 - MyBatis
${}用于WHERE条件值 → 高危 - JDBC 使用 PreparedStatement 且
?占位 → 安全,不报 - JPA 使用
@Param+:paramName→ 安全,不报
CWE: CWE-89
规则 2: 反序列化
Grep 模式:
ObjectInputStreamreadObject\s*\(readUnshared\s*\(XMLDecoderHessian(Input|2Input)new\s+Yaml\(\)\.load(SnakeYAML 无 SafeConstructor)JSON\.parse.*Feature\.SupportAutoType(FastJSON autoType)fromXML\s*\((XStream)
判断是否漏洞:
- 输入来自网络/文件/用户参数 → 高危
- 有 ObjectInputFilter / 白名单 / SafeConstructor → 不报
- SnakeYAML 使用
new Yaml(new SafeConstructor())→ 安全
CWE: CWE-502
规则 3: JNDI 注入
Grep 模式:
InitialContext\s*\(\.lookup\s*\(JndiTemplateJndiLocatorDelegate
判断是否漏洞:
- lookup 参数含变量拼接或来自外部输入 → 高危
- lookup 参数是硬编码的
java:comp/env/前缀 → 安全
CWE: CWE-917
规则 4: 命令注入
Grep 模式:
Runtime\.getRuntime\(\)\s*\.exec\s*\(new\s+ProcessBuilder\s*\(Process\s+.*=.*\.exec\(
判断是否漏洞:
- 命令字符串包含外部输入拼接 → 高危
- 使用数组形式传参且参数固定 → 安全
- 参数来自配置文件且无用户可控 → 低风险
CWE: CWE-78
规则 5: XXE
Grep 模式:
DocumentBuilderFactorySAXParserFactoryXMLInputFactoryXMLReader
判断是否漏洞:
- Read 上下文,搜索以下安全配置是否存在:
setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)setFeature("http://xml.org/sax/features/external-general-entities", false)setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "")
- 无安全配置 → 中危(需确认输入是否可控)
- 有安全配置 → 不报
CWE: CWE-611
规则 6: SSRF
Grep 模式:
new\s+URL\s*\(HttpURLConnectionRestTemplate\s*\(.*\.getForObject\s*\(OkHttpClientHttpClient\.newHttpClientJsoup\.connect\s*\(
判断是否漏洞:
- URL 参数来自
@RequestParam、@PathVariable、请求体 → 高危 - URL 硬编码或来自配置 → 不报
- 有 URL 白名单校验 → 不报
CWE: CWE-918
规则 7: 路径穿越
Grep 模式:
new\s+File\s*\(.*\+(拼接路径)Paths\.get\s*\(.*\+FileInputStream\s*\(.*\+FileOutputStream\s*\(.*\+
判断是否漏洞:
- 路径拼接了
@RequestParam/外部输入 → 中危 - 有
..过滤、normalize()、白名单 → 不报 - 路径纯内部生成 → 不报
CWE: CWE-22
规则 8: SpEL 注入
Grep 模式:
SpelExpressionParserExpressionParser\s*.*=.*new\.parseExpression\s*\(@Value\s*\(\s*"#\{(动态 SpEL)
判断是否漏洞:
- 表达式内容含外部输入 → 高危
@Value引用${}属性占位符 → 安全(非 SpEL)- SimpleEvaluationContext → 低风险(受限上下文)
CWE: CWE-917
规则 9: 硬编码敏感信息
Grep 模式(在 .java 和 .properties/.yml 中搜索):
password\s*=\s*"[^"]+"(secret|secretKey|accessKey|apiKey|appKey|token)\s*=\s*"[^"]+"jdbc:.*password=(AK|SK|ACCESS_KEY|SECRET_KEY)\s*=\s*"[^"]+"
排除:
src/test/目录- 文件名含
example、sample、template、demo - 值为占位符:
${...}、xxx、changeme、your-*、空字符串
CWE: CWE-798
规则 10: 不安全加密
Grep 模式:
Cipher\.getInstance\s*\(\s*"DESCipher\.getInstance\s*\(\s*"AES/ECBMessageDigest\.getInstance\s*\(\s*"MD5MessageDigest\.getInstance\s*\(\s*"SHA-1"(注意不匹配 SHA-256)new\s+Random\s*\((非 SecureRandom)
判断是否漏洞:
- 用于密码存储/签名/加密传输 → 中危
- 用于非安全场景(日志去重、缓存 key 生成等)→ 不报
new Random()用于安全场景(token/验证码/密钥)→ 低危
CWE: CWE-327 / CWE-330
规则 11: 文件上传
Grep 模式:
MultipartFile@RequestParam.*[Ff]ileCommonsMultipartFiletransferTo\s*\(
判断是否漏洞:
- 无文件后缀校验 → 中危
- 无 Content-Type 校验 → 低危
- 直接用原始文件名存储 → 中危(路径穿越风险)
- 有白名单后缀 + 重命名 → 安全
CWE: CWE-434
规则 12: 权限配置缺陷
Grep 模式:
antMatchers\s*\(.*"/\*\*".*\)\s*\.permitAllauthorizeRequests.*anyRequest.*permitAllfilterChainDefinitionMap.*anonShiroFilterFactoryBean@PreAuthorize(检查是否有遗漏的敏感接口)
判断是否漏洞:
/**全放行 → 高危(需确认是否有意为之)- 管理接口(
/admin/**、/api/internal/**)未配置认证 → 高危 - Shiro 路径配置可被 URL 编码/双斜线绕过 → 中危
CWE: CWE-862
Phase 4: 报告生成
将 Phase 2 和 Phase 3 的所有发现汇总,生成 {项目名}-audit-report.md 到项目根目录。
报告模板
# {项目名} 安全审计报告
**审计时间**: YYYY-MM-DD
**项目路径**: {绝对路径}
**构建工具**: Maven / Gradle
**主要框架**: {Phase 1 识别的框架列表}
**Java 源文件数**: {统计}
**依赖组件数**: {统计}
---
## 审计概要
| 类别 | 高危 | 中危 | 低危 | 信息 |
|------|------|------|------|------|
| SCA 依赖漏洞 | x | x | x | x |
| SAST 源码漏洞 | x | x | x | x |
| **合计** | x | x | x | x |
---
## 一、SCA 依赖漏洞
### [高危] CVE-XXXX-XXXXX - {漏洞名称}
- **组件**: groupId:artifactId:version
- **安全版本**: >= x.y.z
- **影响**: {漏洞影响描述}
- **修复建议**: 升级到 {安全版本}
---
## 二、SAST 源码漏洞
### [高危/中危/低危] {漏洞类型} - {简要描述}
- **文件**: src/main/java/com/example/XxxService.java:42
- **代码**:
\```java
// 漏洞代码片段(5-10 行上下文)
\```
- **分析**: {为什么这是漏洞,攻击路径}
- **CWE**: CWE-XXX
- **CVSS 建议**: X.X (High/Medium/Low)
- **修复建议**: {具体修复方法 + 修复代码示例}
---
## 三、审计覆盖范围
- 扫描 Java 源文件: xxx 个
- 扫描 XML 配置文件: xxx 个
- 扫描代码行数(估算): xxx 行
- SCA 检测组件数: xxx 个
- SAST 检测规则数: 12 类
严重等级定义
- 高危: RCE、SQL 注入(WHERE 条件)、反序列化(可控输入)、JNDI 注入、命令注入、已知高危 CVE
- 中危: SSRF、XXE、路径穿越、SpEL 注入、SQL 注入(ORDER BY)、文件上传缺陷、Druid 未授权、权限配置缺陷
- 低危: 硬编码密钥、不安全加密、弱随机数
- 信息: 测试代码中的发现、已防护的模式
无发现时
如果审计未发现漏洞,报告仍然生成,审计概要全部为 0,并注明「未发现明显安全问题」。
完成后
输出一行总结:
审计完成,报告已保存到
{项目名}-audit-report.md。发现 X 个高危、Y 个中危、Z 个低危漏洞。

