You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:05:18