Mybatis框架常见SQL注入攻击以及解决方案

一. 什么是SQL 注入

关于SQL 注入在科普中国的词条上是这样解释的:SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

在mybatis 中最常见的注入风险是书写的时候使用${}

来举一个很简单反例

select name from user_info where id = ${id}

正例

select name from user_info where id = #{id}

Mybatis 中这样书写SQL 语句无疑是有SQL 注入风险的,为什么${} 有注入的风险而#{} 没有注入风险?

在来理清#{} 和 ${}的区别之前我们先回顾 preparedstatement和statement的其中一些区别

1、PreparedStatement是预编译的,可以批量处理数据,statement则相反。

2、传递给PreparedStatement对象的参数可以被强制进行类型转换,statement则相反。

3 、 #{ }是预编译处理,MyBatis在处理#{ }时,它会将sql中的#{ }替换为?,然后调用PreparedStatement的set方法来赋值,传入字符串后,会在值两边加上单引号,如上面的值 “1,ab,c”就会变成“ ‘1,ab,c’ ”

4、 是 字 符 串 替 换 , M y B a t i s 在 处 理 { }是字符串替换, MyBatis在处理 MyBatis{ }时,它会将sql中的${ }替换为变量的值,传入的数据不会加两边加上单引号。

使用${ }会导致sql注入!

二 、 在mybatis 中常犯的错误有以下三种

1. 模糊查询

反例

select name from user_info where name like ‘%${name}%

有些程序员不留意就会犯这个错误,因为以下的写法Mybatis 是会报错的,所以选择用了 ${name}

select name from user_info where name like ‘%#{name}%// 这样写Mybatis 会报错

解决方案:

正例

select name from user_info where name like concat(%,#{name},%)

2. in 之后传的参数

同样的在in 之后使用 #{} Mybatis 也会报错,很多同事会用${} 代替

反例

select name from user_info where id in (${ids})

解决方案:
正例

select name from user_info where id in <foreach collection="ids" item="item" open="("separatosr="," close=")">

3. order by 之后传的参数

同样的在order by 之后使用 #{} Mybatis 也会报错,很多同事会用${} 代替

反例

select name from user_info order by ${id}

解决方案:
正例

select name from user_info order by concat(%,#{id},%)

你可能感兴趣的:(mybatis,mysql,java,数据库)