Java预防SQL注入的具体实践方法

 更新时间:2025年01月22日 08:35:44   作者:Planter  
在 Java 中预防 SQL 注入的核心是 避免直接拼接 SQL 语句,并通过参数化查询、ORM 框架和严格的输入验证来实现安全防护,以下是具体实践方法,感兴趣的小伙伴跟着小编一起来看看吧

1. 强制使用 PreparedStatement(参数化查询)

原理:将 SQL 语句结构与用户输入数据分离,确保输入内容始终作为“数据”处理,而非可执行的代码。

正确示例:

String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
try (Connection conn = dataSource.getConnection();
     PreparedStatement pstmt = conn.prepareStatement(sql)) {
    
    pstmt.setString(1, username); // 自动转义特殊字符(如 ' -> \')
    pstmt.setString(2, password);
    
    try (ResultSet rs = pstmt.executeQuery()) {
        // 处理结果
    }
}

错误做法(高危!):

// 直接拼接 SQL(存在注入风险!)
String sql = "SELECT * FROM users WHERE username = '" + username + "'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);

2. 使用 ORM 框架(如 Hibernate/JPA)

ORM 框架会自动生成参数化查询,减少手写 SQL 的注入风险。

Hibernate 示例:

// 使用 Hibernate Criteria API
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);

query.where(
    cb.equal(root.get("username"), username),
    cb.equal(root.get("password"), password)
);

User user = session.createQuery(query).uniqueResult();

HQL 参数化:

String hql = "FROM User WHERE username = :username";
Query<User> query = session.createQuery(hql, User.class);
query.setParameter("username", username);
User user = query.uniqueResult();

3. 输入验证与过滤

白名单校验:

// 校验用户名是否符合规则(仅允许字母、数字、下划线)
if (!username.matches("^[a-zA-Z0-9_]{4,20}$")) {
    throw new IllegalArgumentException("Invalid username");
}

转义特殊字符(备用方案):

如果必须拼接 SQL(如动态表名),需严格过滤:

// 使用 Apache Commons Text 转义
String safeInput = StringEscapeUtils.escapeSql(input); // 仅适用于简单场景,不推荐依赖!

4. 避免动态拼接 SQL

高危场景:动态表名、列名等无法通过 PreparedStatement 参数化。
安全做法:使用白名单校验合法值:

// 动态表名校验(只允许预定义的合法表名)
Set<String> validTables = Set.of("users", "products");
if (!validTables.contains(tableName)) {
    throw new IllegalArgumentException("Invalid table name");
}
String sql = "SELECT * FROM " + tableName; // 此时拼接是安全的

5. 数据库配置与权限

  • 最小权限原则:应用使用的数据库账号应仅拥有 SELECTINSERTUPDATE 等必要权限,禁止 DROPGRANT 等高危操作。

  • 禁用敏感函数:如 MySQL 的 LOAD_FILEINTO OUTFILE

6. 其他安全措施

隐藏错误信息:

try {
    // 执行数据库操作
} catch (SQLException e) {
    // 生产环境返回通用错误,避免泄露细节
    logger.error("Database error", e);
    throw new RuntimeException("Internal server error");
}

使用安全工具:

  • OWASP ESAPI:提供安全的 SQL 转义方法。

  • SQL 注入扫描工具:集成 sqlmapSonarQube 进行代码审计。

总结:Java 防御 SQL 注入的核心规则

场景

安全做法

高风险做法(避免!)

执行 SQL 查询

使用 PreparedStatement 参数化

拼接字符串生成 SQL

动态表名/列名

白名单校验合法值

直接拼接用户输入

输入验证

正则表达式白名单过滤

仅在前端验证或不做验证

错误信息处理

记录日志,返回通用错误提示

返回详细数据库错误信息

ORM 框架

优先使用 Hibernate/JPA 的 Criteria 或 HQL

手动拼接 HQL 或 JPQL

关键点

  • 绝不信任用户输入:所有外部输入(包括 HTTP 请求参数、Cookie、Headers)均需验证和转义。

  • 代码审查:定期检查项目中是否存在 Statement 或字符串拼接 SQL 的代码。

  • 依赖更新:确保数据库驱动和 ORM 框架保持最新版本,修复已知漏洞。

以上就是Java预防SQL注入的具体实践方法的详细内容,更多关于Java预防SQL注入的资料请关注脚本之家其它相关文章!

相关文章

  • java编程实现多人聊天室功能

    java编程实现多人聊天室功能

    这篇文章主要为大家详细介绍了java编程实现多人聊天室功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • MyBatisPlus深入探究映射匹配的兼容性

    MyBatisPlus深入探究映射匹配的兼容性

    在最近的工作中,碰到一个比较复杂的返回结果,发现简单映射已经解决不了这个问题了,只好去求助百度,学习mybatis映射匹配应该怎么写,将学习笔记结合工作碰到的问题写下本文,供自身查漏补缺,同时已被不时之需
    2022-08-08
  • 解决IDEA的maven项目中没有新建Servlet文件的选项问题

    解决IDEA的maven项目中没有新建Servlet文件的选项问题

    这篇文章主要介绍了IDEA的maven项目中没有新建Servlet文件的选项问题及解决方法,本文给大家分享问题原因就解决方法,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Java中@ConditionalOnProperty注解使用

    Java中@ConditionalOnProperty注解使用

    在Spring Boot中,@ConditionalOnProperty注解是一种方便的工具,用于根据应用程序配置文件中的属性值来控制Bean的创建和加载,本文就来介绍一下Java中@ConditionalOnProperty注解使用,感兴趣的可以了解一下
    2023-11-11
  • Java NumberFormat格式化float类型的bug

    Java NumberFormat格式化float类型的bug

    今天小编就为大家分享一篇关于Java NumberFormat格式化float类型的bug,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • 详解Java递归实现树形结构的两种方式

    详解Java递归实现树形结构的两种方式

    在开发的过程中,很多业务场景需要一个树形结构的结果集进行前端展示,也可以理解为是一个无限父子结构,常见的有报表指标结构、菜单结构等,这篇文章主要介绍了Java递归实现树形结构的两种方式,需要的朋友可以参考下
    2022-10-10
  • SpringBoot各种注解详解

    SpringBoot各种注解详解

    SpringBoot的一个核心功能是IOC,就是将Bean初始化加载到容器中,Bean是如何加载到容器的,可以使用SpringBoot注解方式或者Spring XML配置方式。SpringBoot注解方式减少了配置文件内容,更加便于管理,并且使用注解可以大大提高了开发效率
    2022-12-12
  • SpringCloud-Alibaba-Nacos启动失败解决方案

    SpringCloud-Alibaba-Nacos启动失败解决方案

    这篇文章主要介绍了SpringCloud-Alibaba-Nacos启动失败解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • spring-@Autowired注入与构造函数注入使用方式

    spring-@Autowired注入与构造函数注入使用方式

    这篇文章主要介绍了spring-@Autowired注入与构造函数注入使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • java常用数据流应用实例解析

    java常用数据流应用实例解析

    这篇文章主要介绍了java常用数据流应用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12

最新评论