mybatis java sql注入_java持久化 mybatis 中#{}和${}与sql注入问题(一)

大巧若拙

#{}

#{} 底层通过prepareStatement对当前传入的sql进行了预编译,一个 #{ } 被解析为一个参数占位符 ?; #{} 解析之后会将String类型的数据自动加上引号,其他数据类型不会;#{} 很大程度上可以防止sql注入(sql注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作)

这篇文章https://www.jianshu.com/p/19a9f2340ebe演示了jdbc的prepareStatement预编译防止sql注入,会给危险的单引号转义

#{} 一般用在insert的字段和where条件中,用来防止sql注入

${}

${}仅仅为一个纯粹的 string 替换,在动态sql解析阶段将会进行变量替换;${} 解析之后是什么就是什么;

${} 用在sql字符串拼接中,使用时需要非常谨慎,sql注入可不是闹着玩的。但是像一些没有直接和系统用户接触的功能如动态切换表名,库名呀就不存在注入问题了。一旦要使用在要被用户直接接触的sql中,一定要注意!

${}出现sql注入问题演示

编写mapper接口

@Select("select * from user where name = #{name}")

List sqltest1(String name);

进行测试传入参数为 1' OR 1='1

@Test

public void testInsert(){

List users = mapper.sqltest1("1' OR 1='1 ");

for (User user : users) {

System.out.println(user);

}

}

因为字段里main包含单引号 ,所以最终因为${}拼接出来的sql字符串变成了这样。所以把所有的user信息均查出来了

select * from user where name = '1' OR 1='1 ';

8549841d24da

image.png

那么我们使用#{}进行对比试验,编写mapper接口

@Select("select * from user where name = #{name}")

List sqltest1(String name);

最终的sql什么都没查到,执行结果如下

8549841d24da

image.png

查看mysql全日志,发现单引号被转义!

8549841d24da

image.png

动态指定order by 排序字段

mybatis排序使用order by传入列名时使用$而不是#

如果使用#,会自动给列名加上单引号,实验如下

@Select("select * from user order by #{column}")

List sqltest1(String column);

@Test

public void testInsert(){

List users = mapper.sqltest1("name");

}

执行的sql如下,此时执行排序的是一个字符串字面量,是没有任何效果的

8549841d24da

image.png

我们来使用${}试试

@Select("select * from user order by ${column}")

List sqltest1(String column);

8549841d24da

image.png

如此看来,这时候需要使用${}

like模糊匹配

编写mapper接口

@Select("select * from user where name like '%${name}%'")

List sqltest2(String name);

测试

@Test

public void testInsert(){

List users = mapper.sqltest2("yin");

for (User user : users) {

System.out.println(user);

}

}

发出sql如下,没问题

8549841d24da

image.png

使用#{}做对比试验

@Select("select * from user where name like '%#{name}%'")

List sqltest2(String name);

测试直接报错如下

java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).

总结

初步看来动态指定order by 排序字段、like模糊匹配都需要使用${},但是这种方式会带来sql注入问题。那我们应该如何解决?

使用注意

尽量采用“#{}”这样的格式。若不得不使用“${}”这样的参数请做好防止sql注入的操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值