通过处理参数和instr处理SQL注入

本文关注Web安全中的SQL注入问题,提出了通过使用SQL内置的instr函数处理LIKE场景的注入,并通过参数校验来防范IN场景的注入。在LIKE查询中,用instr替换LIKE以提高效率并避免注入;对于IN查询,建议在代码层面预先校验参数,特别是针对整数类型的参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL注入

针对web安全问题,需要将项目中mybatis涉及${}的代码全部改成#{},由于涉及$的代码多是in和like,现在提供以下解决思路

in和like的场景

模糊查询,涉及多个字段
 name like '%${name}%'

条件查询 String ids; // ids:1,2,3
形如id这样类型为int的字段
 id in (${ids})

通过instr处理like场景的sql注入

针对name like ‘%${name}%’ 这样的模式查询
使用sql内建函数
instr(str, substr[, position[, occurrence]])替代

  • str:源字符
  • substr:目标字符
  • position:初始索引
  • occurrence:出现次数
instr(name, #{name,jdbcType=VARCHAR})>0  替代 name like '%${name}%'

使用instr的优势在于,当数据量很多时instr的效率比like要高(索引对instr有效)

注意:此方式只能出来like模糊查询的sql注入问题

通过校验参数处理in场景的sql注入

针对id in (${ids})这样条件查询中插入的语句,在代码中对参数进行校验


/**
 * Created by white_while
 * @author white_while
 */
public class CheckSqlParam {
    private CheckSqlParam() {}

    public static boolean checkParam(Map<Object, Object> paramMap, Set<String> ids) {
        boolean outcome = true;
        // 校验一下数据库类型为int的参数是否存在sql注入的风险
        Map<String, Object> result = new HashMap<String, Object>(){{
            put("param", null);
        }};
        try {
            paramMap.entrySet().stream().forEach(entry -> {
                boolean flag = ids.contains(entry.getKey());
                if (flag) {
                    result.put("param", entry);
                    String str = (String) entry.getValue();
                    // 将参数强转为int,若报错则传入参数有误
                    Arrays.stream(str.split(",")).forEach(Integer::parseInt);
                }
            });
        } catch (NumberFormatException e) {
            outcome = false;
        }
        return outcome;
    }
}

调用方:

 public Result getPojosOnCondition(Map<Object, Object> pojoMap) {
        // 校验一下参数是否存在sql注入的风险
        // ids applicationId userIds
        Set<String> ids = new HashSet<String>(Arrays.asList("ids", "applicationId", "userIds"));
        boolean outcome = CheckSqlParam.checkParam(pojoMap, ids);
        if (!outcome) {
            return new Result("参数有误");
        }
        ...
}

注意:此方式只能处理用于in的数据库类型为int的参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值