当前位置: 首页 > news >正文

【Java代码审计 | 第四篇】SQL注入防范

文章目录

    • Java SQL注入防范
      • 类型转换
      • 预编译查询(PreparedStatement)
      • 使用 ORM 框架(如 MyBatis、Hibernate)
      • 白名单限制
        • ORDER BY 语句
        • LIKE 语句
      • 限制数据库权限
      • 过滤和转义特殊字符

在这里插入图片描述

Java SQL注入防范

类型转换

Java 是强类型语言,因此直接的数值型 SQL 注入较少,但仍需要注意参数类型的安全性。

int id = Integer.valueOf(req.getParameter("id"));

这样可以确保 id 变量是整数,避免输入 1 OR 1=1 之类的 SQL 语句攻击。

预编译查询(PreparedStatement)

预编译(Parameterized Queries)是防止 SQL 注入的最好方法,能够确保用户输入的数据不会被解析为 SQL 代码。

例如:

public User getUserById(String id) throws SQLException {
    Connection connection = JDBCTOOLS.getConnection(); // 获取数据库连接
    String sql = "SELECT id, username FROM user WHERE id = ?";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setString(1, id);
    ResultSet resultSet = preparedStatement.executeQuery();
    
    if (resultSet.next()) {
        return new User(resultSet.getInt("id"), resultSet.getString("username"));
    }
    return null;
}

使用 ORM 框架(如 MyBatis、Hibernate)

ORM 框架能够自动处理 SQL 预编译,减少 SQL 注入的风险。

例如:

@Mapper
public interface CategoryMapper {
    @Select("SELECT * FROM category_ WHERE name = #{name}")
    Category getByName(String name);
}

白名单限制

某些情况下,用户输入可能用于 ORDER BYINLIKE 等 SQL 语句,预编译无法有效防止注入,这时可使用白名单校验。

ORDER BY 语句
private String checkSort(String sortBy) {
    List<String> columns = Arrays.asList("id", "username", "email");

	// 若传入的字段在允许列表内,则返回原字段;否则返回默认字段 "id"
    return columns.contains(sortBy) ? sortBy : "id";
}

这里通过 checkSort 方法,限定 ORDER BY 只能使用 白名单中的字段(id、username、email),如果 sortBy 不是合法字段,则默认按 id 排序。

String sql = "SELECT * FROM users ORDER BY " + checkSort(sortColumn);
LIKE 语句
String sql = "SELECT * FROM users WHERE username LIKE CONCAT('%', ?, '%')";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, userInput);

这里使用了预编译(PreparedStatement),将 userInput 作为参数传递,而不是直接拼接到 SQL 语句中。

限制数据库权限

数据库用户权限应遵循最小权限原则,避免 root 账户执行 SQL 语句。

CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'XXXX';

1、CREATE USER:在 MySQL 数据库中创建一个新用户。
2、‘app_user’@‘localhost’:用户名是 app_user。
3、@‘localhost’ 指定该用户只能从本机(localhost)连接到数据库,不能从其他 IP 访问。
4、IDENTIFIED BY ‘XXXX’:设置该用户的密码为 ‘XXXX’。

GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'app_user'@'localhost';

1、GRANT:授予数据库权限。
2、SELECT, INSERT, UPDATE:允许 app_user 在数据库 mydb 中执行 查询(SELECT)、插入(INSERT)、更新(UPDATE) 操作。
3、ON mydb.*:作用范围是 mydb 数据库中的所有表(* 代表所有表)。
4、TO ‘app_user’@‘localhost’:只将这些权限授予 本机的 app_user。

过滤和转义特殊字符

可以对用户输入进行严格的字符过滤,但不建议完全依赖此方法。

public static String sanitize(String input) {
    return input.replaceAll("[';--]", "");
}

replaceAll() 会将单引号 (')、分号 (;)、双减号 (–)替换为空字符串 “”,即删除这些字符。

相关文章:

  • 从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十二) socketio 消息处理
  • Git 如何配置多个远程仓库和免密登录?
  • ruoyi-vue使用线程池进行异步开发
  • pandas-基础(数据结构及文件访问)
  • 【2025年24期免费获取股票数据API接口】实例演示五种主流语言获取股票行情api接口之沪深A股最近10天资金流入趋势数据获取实例演示及接口API说明文档
  • 在Oracle中编写雪花算法升学雪花ID
  • 基于python大数据的汽车舆情可视化及分析系统
  • MySQL的日志
  • 【AUTOSAR 基础软件】存储栈(NvM、MemIf、Fee)详解
  • 蓝桥杯嵌入式组第七届省赛题目解析+STM32G431RBT6实现源码
  • git本地仓库链接远程仓库
  • 【Linux系统编程】初识系统编程
  • visual studio 2022 E0020: 未定义标识符 “string“
  • shell学习-第四天
  • Qt常用控件之 纵向列表QListWidget
  • 边界网关协议(BGP)技术详解:原理、应用与配置实践
  • Django与数据库
  • Redis数据结构——set
  • C语言(队列)
  • 算法.习题篇
  • 开发一个手机系统有多难/苏州网站seo服务
  • 垂直型b2c网站有哪些/网站接广告
  • 建设网站需要虚拟空间/宁国网络推广
  • 电子商务网站策划方案/宁波seo排名外包公司
  • 做网站怎么给客户打电话/哪家培训机构学校好
  • web网站开发毕设/郑州seo技术