Spring Boot 项目如何防止 SQL 注入攻击的具体配置方案?

文章导读
Spring Boot 本身没有一键开启的“防 SQL 注入开关”,核心在于正确使用 ORM 框架的参数绑定功能,避免手动拼接 SQL 字符串。
📋 目录
  1. 核心原理与配置说明
  2. 代码修复实战
  3. 验证方法(仅限测试环境)
  4. 常见坑与排查
  5. 参考来源
A A

Spring Boot 项目如何防止 SQL 注入攻击?代码规范与最佳实践

Spring Boot 本身没有一键开启的“防 SQL 注入开关”,核心在于正确使用 ORM 框架的参数绑定功能,避免手动拼接 SQL 字符串。

先说结论:防御 SQL 注入主要靠代码规范而非配置开关,必须使用预编译语句。

  • 先判断:检查项目中是否存在动态拼接 SQL 的代码。
  • 优先做:将所有查询改为参数化查询(PreparedStatement)。
  • 再验证:通过安全扫描或手动测试确认漏洞已修复。

核心原理与配置说明

这不是一个改配置文件的任务,而是一个代码审查和重构的过程。Spring Boot 默认配置中不存在专门用于防御 SQL 注入的属性开关。

1. 依赖配置

为了在 Controller 层进行有效的输入验证,建议引入验证依赖。在 pom.xml 中添加:

<dependency>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-starter-validation</artifactId>\n</dependency>

2. 应用配置文件

application.propertiesapplication.yml 中,没有特定的 SQL 注入防御配置项。重点应放在数据库连接账号的权限控制上,确保应用账号仅拥有最小必要权限(如禁止 DROP、ALTER 权限)。

代码修复实战

重点检查所有涉及数据库查询的地方,确保用户输入没有直接拼接到 SQL 语句中。

Spring Boot 项目如何防止 SQL 注入攻击的具体配置方案?

1. Spring Data JPA 查询

避免在 @Query 注解中拼接字符串。错误写法是将变量直接连入 SQL 字符串,正确写法是使用 ?1:param 占位符。

错误示例:@Query("SELECT u FROM User u WHERE u.name = '" + name + "'")

正确示例:@Query("SELECT u FROM User u WHERE u.name = ?1")

2. MyBatis XML 配置

在 MyBatis 中,严格区分 #{} ${}#{} 会进行预编译处理,是安全的;${} 是直接字符串替换,存在注入风险。除非是动态表名等无法使用占位符的特殊场景,否则一律使用 #{}

正确示例:<select id="findUser" resultType="User"> SELECT * FROM users WHERE id = #{id} </select>

Spring Boot 项目如何防止 SQL 注入攻击的具体配置方案?

3. Controller 层输入验证

在 Controller 层使用 Hibernate Validator 对输入参数进行格式校验,减少非法字符进入业务层的机会。在参数前添加 @Valid@NotNull 等注解。

DTO 示例:

public class UserQueryDTO {\n    @NotBlank(message = "用户名不能为空")\n    private String name;\n    // getters and setters\n}

Controller 示例:

@PostMapping("/search")\npublic ResponseEntity<List<User>> search(@Valid @RequestBody UserQueryDTO dto) {\n    // 业务逻辑\n}

验证方法(仅限测试环境)

警告:严禁在生产环境进行注入测试,以下操作必须在隔离的测试环境中进行。

1. 手动测试

在测试环境的登录框或搜索框中输入典型的注入 Payload,例如 ' OR '1'='1。如果系统返回错误信息或绕过了验证,说明存在漏洞;如果系统提示无结果或输入非法,则可能已防御。

Spring Boot 项目如何防止 SQL 注入攻击的具体配置方案?

2. 代码扫描

使用静态代码分析工具(如 SonarQube)扫描项目,配置 SQL 注入规则集。查看是否有报告指出存在字符串拼接 SQL 的情况。

3. 动态扫描

使用 OWASP ZAP 等安全测试工具对运行中的项目进行扫描,观察是否有 SQL 注入相关的报警。

常见坑与排查

1. 模糊查询的拼接

在做 LIKE 查询时,容易写成 "%" + keyword + "%" 拼接到 SQL 中。正确做法是在 Java 代码中处理好百分号,然后传给占位符,例如 param = "%" + keyword + "%",SQL 中仍写 LIKE ?1

2. 排序字段动态化

ORDER BY 后面的字段名通常不能使用占位符。如果允许用户指定排序字段,必须在代码中维护一个白名单,只允许传入预定义的字段名,不要直接使用用户输入。

3. 批量导入功能

批量插入数据时,为了性能有时会拼接多条 VALUES 语句。这种情况下需要严格校验每一条数据的合法性,或者使用 JDBC 的批量提交功能,而不是字符串拼接。

参考来源

  • OWASP, SQL Injection Prevention Cheat Sheet, https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
  • Spring Framework, Spring Data JPA - Query Methods, https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
  • MyBatis Documentation, Dynamic SQL, https://mybatis.org/mybatis-3/dynamic-sql.html