综合java案例,防守漏洞怎么识别定位?

wen java案例 2

Java 案例中防守漏洞的识别与定位方法

"防守漏洞"在 Java 安全审计中通常指代码防护缺失或失效导致的可利用风险点,下面结合真实案例,系统讲解识别与定位方法。

综合java案例,防守漏洞怎么识别定位?


漏洞识别的四大维度

输入验证缺失(最常见)

案例:SQL 注入

// 漏洞代码
public User getUser(String username) {
    String sql = "SELECT * FROM users WHERE name = '" + username + "'";
    return jdbcTemplate.queryForObject(sql, User.class);
}

识别要点:

  • 字符串拼接 SQL / HQL / JPQL
  • 未使用 PreparedStatement 或 MyBatis
  • 动态表名/排序字段未做白名单

定位方法:全局搜索 + "select、Statement.execute、createQuery(、 在 mapper XML 中的使用。


认证与授权缺陷

案例:越权访问(IDOR)

// 漏洞代码:只校验登录,未校验资源归属
@GetMapping("/order/{id}")
public Order getOrder(@PathVariable Long id, HttpSession session) {
    // 缺少:校验 order.userId == session.userId
    return orderService.findById(id);
}

识别要点:

  • 敏感接口调用 @PreAuthorize/checkPermission 是否缺失
  • 资源类接口是否做了对象级权限校验(不只是角色)
  • 越权检测:换用其他用户 token 访问他人资源

定位方法:Spring Security 配置审查 + 逐接口核对 @PreAuthorize 注解覆盖度。


反序列化与表达式注入

案例:Fastjson 反序列化

// 漏洞代码
String json = request.getParameter("data");
Object obj = JSON.parse(json);  // 未指定 safeMode / AutoType 黑名单

识别要点:

  • ObjectInputStream.readObject() 未做类白名单
  • Fastjson parse/parseObject 未开启 safeMode
  • SpEL/OGNL 中 parseExpression(userInput)
  • Jackson 开启 enableDefaultTyping()

定位方法:搜索 readObject、JSON.parse、SpelExpressionParser、enableDefaultTyping。


敏感信息与加密误用

案例:硬编码密钥 + 弱加密

// 漏洞代码
private static final String KEY = "1234567890abcdef"; // 硬编码
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // 弱算法

识别要点:

  • 硬编码 secret/key/password
  • ECB 模式、DES/MD5/SHA1
  • Random 用于安全场景(应用 SecureRandom)
  • 日志打印敏感字段(身份证、密码、token)

定位方法:静态扫描 getInstance("DES、new Random(、log.info.*password。


实战定位流程(五步法)

① 资产梳理 → ② 入口枚举 → ③ 数据流追踪 → ④ 防护点核查 → ⑤ 动态验证

① 资产梳理

  • 识别 Controller 层入口(@RequestMapping、@GetMapping…)
  • 识别第三方组件版本(pom.xml/build.gradle),对照 CVE(如 Log4Shell、Fastjson)

② 入口枚举

列出所有 外部可控输入点:

  • HTTP 参数、Header、Cookie、Body
  • 文件上传、URL 重定向参数
  • 反序列化入口、RPC 接口

③ 数据流追踪(关键)

从 Source(入口) 追踪到 Sink(危险操作):

Source Sink
request.getParameter Statement.execute
@RequestParam Runtime.exec
上传文件名 new File(path)
JSON body readObject

工具辅助:

  • IDEA 内置 Data Flow Analysis(右键 → Analyze Data Flow to Here)
  • FindBugs/SpotBugs 插件、Semgrep、CodeQL
  • Fortify / SonarQube 做 taint analysis

④ 防护点核查

对每个 Sink 确认是否有防护:

  • SQL → 参数化?
  • 命令执行 → 白名单?
  • 文件路径 → 规范化校验(getCanonicalPath().startsWith(base))?
  • 输出 → 编码/转义?

⑤ 动态验证

  • 构造 payload 实际请求
  • 关注堆栈、错误回显判断后端行为
  • 使用 Burp/Postman 测试越权、注入

典型漏洞速查表

漏洞类型 危险代码特征 定位关键词
SQL 注入 字符串拼接 SQL + "WHERE、execute(、
XSS 直接输出用户输入 response.getWriter().print、视图未转义
命令注入 运行时执行 Runtime.exec、ProcessBuilder
路径遍历 拼接文件路径 new File(base + name)、
SSRF 请求用户提供的 URL new URL(userInput)、RestTemplate
XXE XML 解析未禁外部实体 DocumentBuilderFactory、SAXParser
反序列化 不可信数据反序列化 readObject、JSON.parse
越权 缺对象级校验 无 @PreAuthorize、无归属判断
硬编码 密钥写在代码里 private static final String KEY
弱随机 用 Random 生成 token new Random(

工具组合建议

  1. 静态扫描:SonarQube(基线)+ Semgrep(自定义规则)+ CodeQL(深度数据流)
  2. 依赖检测:mvn dependency-check / OWASP Dependency-Check
  3. 运行时:IAST(如 Contrast)、RASP 观察异常调用链
  4. 人工复核:重点审查 Sink 点上下文,排除误报(如已做白名单)

一个完整案例演示

@PostMapping("/download")
public void download(@RequestParam String filename, HttpServletResponse resp) {
    // Source: filename (外部可控)
    File file = new File("/data/files/" + filename);   // Sink: 路径拼接
    // 缺失防护:未校验 ../
    Files.copy(file.toPath(), resp.getOutputStream());
}

定位步骤:

  1. 入口:@RequestParam filename
  2. 数据流:filename → new File(...) → Files.copy
  3. 防护缺失:无 getCanonicalPath 校验、无白名单
  4. 验证:filename=../../etc/passwd 读取系统文件
  5. 修复:
    Path base = Paths.get("/data/files").toRealPath();
    Path target = base.resolve(filename).normalize();
    if (!target.startsWith(base)) throw new SecurityException("非法路径");

识别 = 找 Source 和 Sink;定位 = 追踪数据流 + 核查防护点;确认 = 动态验证。 核心思路是「每个外部输入到敏感操作的通路上,必须存在有效防护」,任何断链处就是潜在漏洞点。

抱歉,评论功能暂时关闭!