360 Secure SkillHub
360 安全技能中心

java-code-audit

对 Java 项目执行静态安全审计:先识别 Maven/Gradle 构建、解析依赖与框架,与内置高危组件 CVE 清单比对;再按 12 类规则(SQL 注入、反序列化、JNDI、命令注入、XXE、SSRF、路径穿越、SpEL、硬编码密钥、不安全加密、文件上传、权限配置)扫描源码,最后在项目根目录生成 Markdown 审计报告。

半夜不睡觉12
半夜不睡觉12
热度 18.77
最近更新 2026-05-10 10:15:59
分类:安全依赖:读写文件应用场景:代码审查 / 报告撰写 / 自动化脚本

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add java-code-audit
Metadata
name
java-code-audit
description
Java 项目静态安全审计。SCA 依赖 CVE 匹配 + SAST 源码危险模式检测(SQL注入/反序列化/JNDI/命令注入/XXE/SSRF/路径穿越/SpEL/硬编码密钥/不安全加密/文件上传/权限配置),输出 Markdown 审计报告。

Java Code Audit - Java 项目静态安全审计

使用方式

/java-code-audit <项目路径>

从 ARGUMENTS 解析项目路径。如果未提供,使用当前工作目录。

声明

此 skill 仅用于已授权的安全审计和研究。


自主执行规则

  1. 不要暂停询问用户
  2. 遇到错误记录后跳过,继续下一项
  3. 保持工具调用密度 — 每次响应尽量并行调用多个工具
  4. 不输出冗长中间过程 — 只输出简短进度标记

Phase 1: 项目侦察

1.1 识别构建工具

并行 Glob 搜索:

  • **/pom.xml → Maven
  • **/build.gradle 或 **/build.gradle.kts → Gradle
  • **/build.xml → Ant

记录构建工具类型和所有构建文件路径。

1.2 解析项目结构

  1. Glob **/src/main/java/**/*.java 统计源码文件数
  2. Glob **/src/main/resources/** 统计资源文件
  3. Glob **/*.xml 定位 MyBatis mapper 等配置文件
  4. 识别多模块结构(多个 pom.xml / build.gradle)

1.3 提取依赖清单

Maven 项目:

  1. Read 根 pom.xml,提取 <properties> 中的版本变量
  2. 提取 <dependencies> 和 <dependencyManagement> 中所有 groupId:artifactId:version
  3. 如果 version 是 ${variable} 形式,从 properties 中解析实际版本
  4. 多模块项目:遍历所有子模块 pom.xml

Gradle 项目:

  1. Read build.gradle,提取 implementation/compile/api 依赖声明
  2. 解析 ext 或 buildscript 中的版本变量
  3. 检查 gradle.properties 中的版本定义

1.4 识别框架

根据依赖清单识别:

  • spring-boot-starter-* → Spring Boot(记录版本)
  • mybatis* → MyBatis
  • shiro-* → Apache Shiro
  • struts2-* → Struts2
  • spring-cloud-* → Spring Cloud
  • spring-security-* → Spring Security
  • fastjson* → FastJSON
  • dubbo* → 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

匹配流程

  1. 对每个依赖,查找 groupId:artifactId 是否命中上表
  2. 命中 → 比对版本是否在高危范围内
  3. 版本在高危范围 → 记录:组件、当前版本、CVE 编号、风险等级、说明、建议升级版本
  4. 版本未解析成功 → 记录为「需人工确认」并标注原因
  5. 未命中表中组件但名称含 log4j/fastjson/shiro/struts/xstream → 也做二次检查

Druid 特殊检查

如果依赖中包含 com.alibaba:druid:

  1. Grep 搜索 stat-view-servlet 或 StatViewServlet
  2. 检查是否配置了 loginUsername 和 loginPassword
  3. 未配置 → 报告为中危:Druid 监控页未授权访问

Phase 3: SAST 源码审计

对 src/main/ 下的源码执行 12 类漏洞检测。每类采用两步法:

  1. Grep 快筛 — 定位可疑文件和行号
  2. 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 模式:

  • ObjectInputStream
  • readObject\s*\(
  • readUnshared\s*\(
  • XMLDecoder
  • Hessian(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*\(
  • JndiTemplate
  • JndiLocatorDelegate

判断是否漏洞:

  • 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 模式:

  • DocumentBuilderFactory
  • SAXParserFactory
  • XMLInputFactory
  • XMLReader

判断是否漏洞:

  • 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*\(
  • HttpURLConnection
  • RestTemplate\s*\(.*\.getForObject\s*\(
  • OkHttpClient
  • HttpClient\.newHttpClient
  • Jsoup\.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 模式:

  • SpelExpressionParser
  • ExpressionParser\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*"DES
  • Cipher\.getInstance\s*\(\s*"AES/ECB
  • MessageDigest\.getInstance\s*\(\s*"MD5
  • MessageDigest\.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]ile
  • CommonsMultipartFile
  • transferTo\s*\(

判断是否漏洞:

  • 无文件后缀校验 → 中危
  • 无 Content-Type 校验 → 低危
  • 直接用原始文件名存储 → 中危(路径穿越风险)
  • 有白名单后缀 + 重命名 → 安全

CWE: CWE-434


规则 12: 权限配置缺陷

Grep 模式:

  • antMatchers\s*\(.*"/\*\*".*\)\s*\.permitAll
  • authorizeRequests.*anyRequest.*permitAll
  • filterChainDefinitionMap.*anon
  • ShiroFilterFactoryBean
  • @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 个低危漏洞。