解决mybatis使用${}时sql注入的问题

没有检索到摘要

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

最近在上线项目的时候,代码审查没有通过,提示有sql注入的风险。

ORDER BY ${orderBy}

很简单的一个排序字段,但是因为使用 ${} 占位符的原因,有sql注入的风险,相信大家平时也经常会使用这个占位符,不知道有没有考虑sql注入的问题,下面简单介绍下 #{} 和 ${} 的区别以及为什么使用 ${} 会有sql注入的问题。

区别
  • #{}是一个参数占位符,对于String类型会自动加上"",其他类型不加。由于Mybatis采用预编译,其后的参数不会再进行SQL编译,所以一定程度上防止SQL注入。
  • ${}是一个简单的String替换,字符串是什么,解析就是什么。
  • 类如order by。假如前端传的参数是id(假设id是String类型),对于order by #{id},对应的sql语句就是 order by “id”;对于order by ${id},对应的sql语句则是order by id。这种情况,当用户传参为id && 1=1 的时候,就会产生难以预计的后果。
解决方法
  • 在原实体类里加入一个map
 public Map<String,String> indexMap=new HashMap<String,String>(){
        {
            put("spaceId","space_id"); // key为前端传的值,value为数据库对应的列值
            put("optTime","opt_time");
        }
    };
  • 当传参时,判断参数是否在map的key中,如果存在的话,就把对应的value作为排序的依赖条件。
if(paramOptLog.getOrderBy()!=null &&Strings.isNullOrEmpty(paramOptLog.getOrderBy())){
            OptLog optLog=new OptLog();
            paramOptLog.setOrderBy(optLog.indexMap.getOrDefault(paramOptLog.getOrderBy(), "id"));
        }
        List<OptLog> list = optLogMapper.query4Page(paramOptLog);
 }
  • 总结就是通过映射,由程序员来决定 ${} 传的参数,即将动态sql转成静态sql的方式可以解决这个问题,这样在实际调用的时候就不会有sql注入的风险了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值