如何处理Checkmarx扫描出的Spring Data JPA项目SQL注入及二阶注入漏洞?
Spring Data JPA SQL注入及二阶注入漏洞修复方案
问题分析
你的代码使用原生SQL查询,虽然通过位置参数?1、?2传递参数,但Checkmarx仍检测到password字段存在注入风险,原因包括:
- 原生SQL的位置参数可能被扫描规则判定为潜在风险点
- 若
password字段存储的是用户输入内容(未做哈希处理),后续用该字段做查询时会触发二阶注入风险
具体修复方案
方案1:改用Spring Data JPA方法命名查询(推荐)
完全避免手写SQL,利用框架自动生成安全的参数绑定查询,彻底消除注入风险:
public interface AccRepository extends BaseRepository<Acc, String> { // 框架自动生成安全的查询语句,无需手动编写SQL Acc findByUsernameAndPassword(String username, String password); }
方案2:优化原生SQL的参数绑定方式
若必须使用原生SQL,改用命名参数替代位置参数,让扫描工具明确识别参数绑定逻辑:
import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; public interface AccRepository extends BaseRepository<Acc, String> { @Query(value = "SELECT * FROM acc WHERE username = :username and password = :password", nativeQuery = true) Acc selectAcc(@Param("username") String username, @Param("password") String password); }
方案3:根源解决二阶注入+提升密码安全性(核心)
永远不要明文存储密码,必须存储密码的哈希值(如BCrypt、Argon2),查询时对用户输入的密码哈希后再匹配:
步骤1:修改Repository层,仅按用户名查询
public interface AccRepository extends BaseRepository<Acc, String> { Acc findByUsername(String username); }
步骤2:服务层实现密码校验逻辑
import org.springframework.security.crypto.password.PasswordEncoder; @Service public class AccService { private final AccRepository accRepository; private final PasswordEncoder passwordEncoder; // 构造注入PasswordEncoder(Spring Security提供) public AccService(AccRepository accRepository, PasswordEncoder passwordEncoder) { this.accRepository = accRepository; this.passwordEncoder = passwordEncoder; } public Acc validateAcc(String username, String rawPassword) { Acc acc = accRepository.findByUsername(username); if (acc != null && passwordEncoder.matches(rawPassword, acc.getPassword())) { return acc; } return null; } }
步骤3:用户注册时存储哈希密码
public Acc createAcc(String username, String rawPassword) { Acc acc = new Acc(); acc.setUsername(username); // 对密码进行哈希后存储 acc.setPassword(passwordEncoder.encode(rawPassword)); return accRepository.save(acc); }
内容的提问来源于stack exchange,提问作者Steven Zhou
相关产品推荐
相关产品推荐

