FindSecBugs是基于字节码的静态分析工具,能识别用户输入未经校验直接拼接SQL、Statement执行动态字符串、MyBatis ${}误用、JPA原生查询未参数化等注入模式,但不分析源码字符串或XML,需结合人工审计。

FindSecBugs 是专为安全漏洞设计的静态分析工具,它能检测 SQL 注入、XSS、硬编码密钥等风险,而 Checkstyle 本身不检测 SQL 注入——它只管格式和命名规范。想靠 Checkstyle 找出 String sql = "SELECT * FROM user WHERE id = " + userId; 这类拼接语句?做不到。
真正起作用的是 FindSecBugs(SpotBugs 的安全插件),它基于字节码分析,能识别危险的 API 调用模式,比如直接将用户输入传给 Statement.execute()、PreparedStatement.setString() 未被调用、或使用了 String.format() 拼接 SQL。
FindSecBugs 能识别哪些 SQL 注入模式
- 用户输入(如
request.getParameter()、HttpServletRequest.getParameter())未经校验/转义,直接进入 JDBC 执行链 - 使用
Statement而非PreparedStatement,且 SQL 字符串含变量拼接 - MyBatis 中
${}占位符出现在非可信上下文(如WHERE ${userInput}),而#{}是安全的 - JPA/Hibernate 中通过
@Query使用原生 SQL 且参数未绑定(如@Query("SELECT * FROM t WHERE name = '" + name + "'"))
FindSecBugs 会报告类似这样的问题:
SQL_INJECTION: Potential SQL injection in method com.example.dao.UserDao.findByName
注意:它不会报 String sql = "SELECT * FROM user WHERE id = ?"; 这种写法——哪怕后面没设参数,它只看“是否用了 ?”这个结构信号,不追踪变量赋值流。
Maven 中集成 findsecbugs-plugin 的关键配置
FindSecBugs 必须作为 spotbugs-maven-plugin 的依赖插件启用,不能单独用旧版 findbugs-maven-plugin(已废弃):
确保项目已编译出
.class文件(compile或package阶段后运行)-
在
pom.xml中添加:<plugin> <groupId>com.github.spotbugs</groupId> <artifactId>spotbugs-maven-plugin</artifactId> <version>4.8.5.0</version> <configuration> <plugins> <plugin> <groupId>com.h3xstream.findsecbugs</groupId> <artifactId>findsecbugs-plugin</artifactId> <version>1.12.0</version> </plugin> </plugins> </configuration> <executions> <execution> <goals><goal>check</goal></goals> </execution> </executions> </plugin> 不要设置
<effort>Min</effort>:默认Default才会启用 SQL 注入相关规则;Min会跳过高开销检测项若项目含 Lombok,需额外加
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>,否则可能因 AST 变形误报
为什么把 Checkstyle 和 FindSecBugs 放一起容易误判风险
-
Checkstyle的RegexpSinglelineJava规则可强行匹配"SELECT.<em>\+.</em>request"这类字符串,但:- 它无法区分
request.getParameter("id")和注释里的示例代码 - 无法判断变量是否真被用于 SQL 执行,纯文本扫描 → 大量误报
- 一旦正则写错(比如漏转义
$),整个模块检查失败
- 它无法区分
-
FindSecBugs基于控制流与数据流建模,只在真实执行路径上触发警告 - 混用二者时,开发者常把
Checkstyle的“风格警告”当成“安全告警”,反而忽略FindSecBugs报出的SQL_INJECTION真实条目
真正该做的,是让 Checkstyle 管住命名(如禁止方法名含 sql)、行宽、缩进;让 FindSecBugs 专注漏洞路径。二者职责边界必须清晰。
FindSecBugs 不会分析源码字符串里的 SQL 片段,也不理解 MyBatis XML 文件中的 <where> 标签逻辑——它只看最终生成的字节码里,用户输入是否“流经危险方法”。这意味着:动态 SQL 构建、反射调用 JDBC、或自定义 ORM 封装层,都可能逃逸检测。人工审计仍不可替代。

















