java代码审计
字数 1608 2025-08-20 18:18:23

Java代码审计全面指南

1. Java编译与反编译

1.1 Java编译过程

  • Java源代码 → (编译) → Java字节码 → (解释器) → 机器码
  • 字节码优势:高效、可移植性高

1.2 反编译工具

  • Fernflower
  • JAD
  • JD-GUI
  • IDEA自带插件

2. Servlet与JSP

2.1 Servlet

  • 处理复杂服务端业务逻辑
  • 含有HttpServlet类,可进行重写
  • Servlet 3.0后使用注解方式描述Servlet
  • 3.0前必须在web.xml中配置

2.2 JSP

  • 会被编译成Java类文件
  • 是特殊的Servlet
  • 在Tomcat中Jasper编译后生成_jsp.java_jsp.class文件

3. 全局控制器与过滤器

3.1 全局控制器搜索

find ~/cms/ -type f -name "*.class" | xargs grep -E "Controller|@RestController|RepositoryRestController"
find ~/cms/ -type f -name "*.class" | xargs grep -E "RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping|RepositoryRestResource"

3.2 全局过滤器

  • 审计时先检查是否存在全局过滤器
  • 常见写法:
<filter>
  <filter-name>SecurityFilter</filter-name>
  <filter-class>com.example.SecurityFilter</filter-class>
  <init-param>
    <param-name>sqlInjIgnoreUrls</param-name>
    <param-value>.*/api/.*</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>SecurityFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

4. 常见漏洞类型

4.1 代码实现安全问题

  • 任意文件操作(上传/下载/遍历/删除/重命名)
  • SQL注入
  • XXE(XML实体注入)
  • 表达式执行(SpEL/OGNL/MVEL2/EL)
  • 系统命令执行(ProcessBuilder)
  • 反序列化攻击
  • Java反射攻击
  • SSRF
  • XSS

4.2 业务安全问题

  • 认证/授权缺陷
  • 验证码缺陷
  • 密码找回逻辑问题
  • 支付逻辑缺陷
  • ORM框架误用
  • CSRF漏洞
  • 前端信任问题
  • 敏感信息泄露
  • 条件竞争
  • 请求频率限制缺失
  • 弱加密算法

5. SQL注入审计

5.1 直接拼接风险

String sql = "SELECT * FROM users WHERE username = '" + request.getParameter("name") + "'";

5.2 预编译使用错误

// 错误示例:占位符但未使用set方法
PreparedStatement st = conn.prepareStatement("SELECT * FROM users WHERE username = ?");
st.setString(1, request.getParameter("name"));  // 必须使用set方法

5.3 MyBatis框架审计

  • 搜索$符号
  • #{}安全,${}存在风险
  • 模糊查询风险:like '%${xxx}%'
  • 无需引号处风险:in(${xxx})order by ${xxx}

6. 表达式注入(SpEL/OGNL)

6.1 SpEL注入示例

String el = "T(java.lang.Runtime).getRuntime().exec(\"open /tmp\")";
ExpressionParser PARSER = new SpelExpressionParser();
Expression exp = PARSER.parseExpression(el);
exp.getValue();  // 执行命令

6.2 审计要点

  • 检查SpelExpressionParser使用处
  • 检查表达式是否用户可控

7. XSS漏洞

7.1 示例代码

@RequestMapping("/xss")
public ModelAndView xss(HttpServletRequest request) {
    String name = request.getParameter("name");
    ModelAndView mav = new ModelAndView("page");
    mav.getModel().put("uname", name);  // 未转义直接输出
    return mav;
}

8. SSRF漏洞

8.1 风险代码

String url = request.getParameter("picurl");
URL pic = new URL(url);
HttpURLConnection con = (HttpURLConnection) pic.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

8.2 审计要点

  • 检查支持的协议:file/ftp/http/https
  • 检查相关函数:
    • HttpClient.execute
    • HttpURLConnection.connect
    • URL.openStream

9. XXE漏洞

9.1 风险代码

SAXReader sax = new SAXReader();
Document document = sax.read(new ByteArrayInputStream(xmldata.getBytes()));

9.2 修复方案

saxReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

10. 反序列化漏洞

10.1 风险点

InputStream in = request.getInputStream();
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();  // 反序列化用户可控数据

10.2 审计要点

检查以下方法:

  • ObjectInputStream.readObject
  • XMLDecoder.readObject
  • Yaml.load
  • XStream.fromXML
  • ObjectMapper.readValue
  • JSON.parseObject

10.3 修复方案

  • 白名单校验
  • 使用ValidatingObjectInputStream
ValidatingObjectInputStream ois = new ValidatingObjectInputStream(bais);
ois.accept(SafeClass.class);  // 只允许反序列化指定类

11. 文件操作漏洞

11.1 路径遍历

File file = new File(request.getParameter("path"));
// 应使用getCanonicalPath()而非getAbsolutePath()

11.2 ZIP文件提取风险

ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
    FileOutputStream fos = new FileOutputStream(entry.getName());  // 未校验路径
    // ...
}

11.3 修复方案

File f = new File(intendedDir, entryName);
String canonicalPath = f.getCanonicalPath();
if (!canonicalPath.startsWith(intendedDirCanonicalPath)) {
    throw new IllegalStateException("非法路径");
}

12. 第三方组件安全

12.1 常见风险组件

  • Struts2
  • Fastjson
  • 不安全的编辑控件

12.2 审计方法

  • 检查组件版本
  • 检查已知漏洞

13. 其他重要漏洞

13.1 URL重定向

String site = request.getParameter("url");
response.sendRedirect(site);  // 未校验URL

13.2 Autobinding

@RequestMapping("/reset")
public String resetHandler(@ModelAttribute User user) {
    // 可能绑定不需要的字段
}

13.3 WebService

  • 检查?wsdl接口
  • 使用BurpSuite WSDL插件测试

14. 审计工具与方法

14.1 代码搜索技巧

  • 全局搜索关键字符串:sql/xml/Runtime.exec
  • 使用IDE的全局搜索功能

14.2 重点关注点

  • 用户输入点
  • 外部数据解析
  • 敏感操作
  • 权限校验

15. 总结

Java代码审计需要全面考虑代码实现和业务逻辑两方面的安全问题,重点关注用户输入处理、数据解析、权限控制等关键环节,结合框架特性和业务场景进行深入分析。

Java代码审计全面指南 1. Java编译与反编译 1.1 Java编译过程 Java源代码 → (编译) → Java字节码 → (解释器) → 机器码 字节码优势:高效、可移植性高 1.2 反编译工具 Fernflower JAD JD-GUI IDEA自带插件 2. Servlet与JSP 2.1 Servlet 处理复杂服务端业务逻辑 含有HttpServlet类,可进行重写 Servlet 3.0后使用注解方式描述Servlet 3.0前必须在web.xml中配置 2.2 JSP 会被编译成Java类文件 是特殊的Servlet 在Tomcat中Jasper编译后生成 _jsp.java 和 _jsp.class 文件 3. 全局控制器与过滤器 3.1 全局控制器搜索 3.2 全局过滤器 审计时先检查是否存在全局过滤器 常见写法: 4. 常见漏洞类型 4.1 代码实现安全问题 任意文件操作(上传/下载/遍历/删除/重命名) SQL注入 XXE(XML实体注入) 表达式执行(SpEL/OGNL/MVEL2/EL) 系统命令执行(ProcessBuilder) 反序列化攻击 Java反射攻击 SSRF XSS 4.2 业务安全问题 认证/授权缺陷 验证码缺陷 密码找回逻辑问题 支付逻辑缺陷 ORM框架误用 CSRF漏洞 前端信任问题 敏感信息泄露 条件竞争 请求频率限制缺失 弱加密算法 5. SQL注入审计 5.1 直接拼接风险 5.2 预编译使用错误 5.3 MyBatis框架审计 搜索 $ 符号 #{} 安全, ${} 存在风险 模糊查询风险: like '%${xxx}%' 无需引号处风险: in(${xxx}) 或 order by ${xxx} 6. 表达式注入(SpEL/OGNL) 6.1 SpEL注入示例 6.2 审计要点 检查 SpelExpressionParser 使用处 检查表达式是否用户可控 7. XSS漏洞 7.1 示例代码 8. SSRF漏洞 8.1 风险代码 8.2 审计要点 检查支持的协议: file / ftp / http / https 等 检查相关函数: HttpClient.execute HttpURLConnection.connect URL.openStream 9. XXE漏洞 9.1 风险代码 9.2 修复方案 10. 反序列化漏洞 10.1 风险点 10.2 审计要点 检查以下方法: ObjectInputStream.readObject XMLDecoder.readObject Yaml.load XStream.fromXML ObjectMapper.readValue JSON.parseObject 10.3 修复方案 白名单校验 使用 ValidatingObjectInputStream 11. 文件操作漏洞 11.1 路径遍历 11.2 ZIP文件提取风险 11.3 修复方案 12. 第三方组件安全 12.1 常见风险组件 Struts2 Fastjson 不安全的编辑控件 12.2 审计方法 检查组件版本 检查已知漏洞 13. 其他重要漏洞 13.1 URL重定向 13.2 Autobinding 13.3 WebService 检查 ?wsdl 接口 使用BurpSuite WSDL插件测试 14. 审计工具与方法 14.1 代码搜索技巧 全局搜索关键字符串: sql / xml / Runtime.exec 等 使用IDE的全局搜索功能 14.2 重点关注点 用户输入点 外部数据解析 敏感操作 权限校验 15. 总结 Java代码审计需要全面考虑代码实现和业务逻辑两方面的安全问题,重点关注用户输入处理、数据解析、权限控制等关键环节,结合框架特性和业务场景进行深入分析。