FunTester Java 模糊测试上手指南

FunTester · July 22, 2025 · 402 hits

模糊测试(Fuzz testing)是一种通过向应用程序输入大量随机或半随机数据来发现漏洞和缺陷的技术。它不仅是安全测试的利器,也是提升代码质量的秘密武器。

模糊测试简介

  • 什么是模糊测试 模糊测试是一种动态测试方法,通过在程序运行时输入数百万个随机、异常或无效的数据,探测系统的崩溃或异常行为,从而发现功能缺陷和安全漏洞。
  • 为何使用模糊测试 与静态安全检测不同,模糊测试在运行时提供具体的错误源以及导致崩溃的输入,误报率极低。它不仅能发现隐藏的安全问题,还能提高代码的鲁棒性和稳定性。举个例子,假如你开发了一个处理用户上传文件的功能,模糊测试可以模拟各种奇怪的文件格式和内容,帮助你发现潜在的崩溃点。

模糊测试能发现的缺陷

模糊测试特别适用于处理复杂或不可信输入的场景,例如媒体解码器、Web 服务器、移动应用或加密工具等。

它能捕获的主要问题包括:

  • 可用性问题:如程序崩溃、死循环、未捕获异常等。
  • 数据验证错误:如 SQL 注入、XXE、XSS、敏感信息泄漏等。
  • 逻辑缺陷:如认证绕过、访问控制漏洞、日志错误等。
  • Cookie 安全问题:如遗漏 SameSite、HttpOnly、Secure 属性。

特别是 OWASP Top 10 中的常见漏洞(如 SQL 注入、XSS、反序列化问题等),模糊测试都能有效检测。

Google Chrome 的模糊测试实践

Google 是模糊测试的忠实粉丝。通过模糊测试,Google 发现了超过 25,000 个 Chrome 缺陷,并将其纳入自动化安全检测流程。Google 还建议开源社区在 Java 软件供应链中采用模糊测试,以增强对内存问题和可利用漏洞的防御能力。

Java 环境下的模糊测试实践

在 Java 环境中,推荐使用 CI Fuzz,一个开源且易于上手的 Java 异常测试工具。它可以无缝集成到 JUnit 测试框架中。

  • 快速上手:通过添加 @FuzzTest 注解即可启动模糊测试,命令如下:
cifuzz init
cifuzz create my_fuzz_test
cifuzz run my_fuzz_test
  • 跨平台支持:支持 Linux、macOS 和 Windows,兼容 Gradle 和 Maven 构建工具。只需安装 Java JDK 和构建系统即可。

  • Maven 配置示例

<dependency>
  <groupId>com.code-intelligence</groupId>
  <artifactId>jazzer-junit</artifactId>
  <version>0.13.0</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <version>5.9.0</version>
  <scope>test</scope>
</dependency>

Java 库的模糊测试示例

假设我们有一个目标类 ExploreMe,它的代码如下:

package com.example;

public class ExploreMe {
  // 模拟一个方法,接收三个参数并进行逻辑判断
  public static void exploreMe(int a, int b, String c) {
    // 检查输入是否满足特定条件
    if (a >= 20000 && b >= 2000000 && b - a < 100000 && c.startsWith("@")) {
      String className = c.substring(1); // 提取类名
      try {
        Class.forName(className); // 尝试加载类
      } catch (ClassNotFoundException ignored) {
        // 忽略类未找到异常
      }
    }
  }
}

模糊测试用例如下:

import com.code-intelligence.jazzer.api.FuzzedDataProvider;
import com.code-intelligence.jazzer.junit.FuzzTest;

public class FuzzTestCase {
  @FuzzTest
  void myFuzzTest(FuzzedDataProvider data) {
    // 从模糊数据提供器中消费一个随机整数
    int a = data.consumeInt();
    // 消费另一个随机整数
    int b = data.consumeInt();
    // 消费剩余数据作为字符串
    String c = data.consumeRemainingAsString();
    // 调用目标方法进行测试
    ExploreMe.exploreMe(a, b, c);
  }
}

当某个输入导致程序崩溃时,该输入会被加入种子集合,后续用于进一步测试。这种机制可以帮助开发者快速定位问题。

总结

模糊测试是一种强大的测试方法,能够发现崩溃、稳定性、逻辑和安全缺陷。对于 Java 开发者来说,结合 CI Fuzz 和 JUnit,可以快速集成模糊测试,提升代码在面对异常输入时的鲁棒性和安全性。

当某个输入导致程序崩溃时,该输入会被加入种子集合,后续用于进一步测试。这种机制可以帮助开发者快速定位问题。

public class ExploreMe {
  public static void exploreMe(int a, int b, String c) {
    if (a >= 20000 && b >= 2000000 && b - a < 100000 && c.startsWith("@")) {
      String className = c.substring(1);
      try {
        Class.forName(className);
      } catch (ClassNotFoundException ignored) {}
    }
  }
}

模拟模糊测试用例:

import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import com.code_intelligence.jazzer.junit.FuzzTest;

public class FuzzTestCase {
  @FuzzTest
  void myFuzzTest(FuzzedDataProvider data) {
    int a = data.consumeInt();
    int b = data.consumeInt();
    String c = data.consumeRemainingAsString();
    ExploreMe.exploreMe(a, b, c);
  }
}

当某输入导致 crash,该输入将被加入种子集合,后续用于进一步测试  。


FunTester 原创精华
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
No Reply at the moment.
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up