MyBatis的SQL注入攻击和动态SQL

SQL注入的危害:
1、数据库被拖库(把数据从数据库拉取出来);
2、重要信息被泄露等;
注入攻击的本质,是把用户输入的数据当做有效代码执行;

举例:
当用户发送GET请求:
https://ke.qq.com/course.jsp?id=1
这是一个课程详情页面,会显示出课程的title和content,程序会接收id参数传递给SQL语句,SQL如下:
SELECT title, content FROM course WHERE id = 1

这是SQL的原义,也是程序员想要得到的结果,但是如果用户改变了id的内容,改为:

https://ke.qq.com/course.jsp?id=1 and 1=2 UNION SELECT username, password FROM admin
此时内部程序执行的SQL语句为:

SELECT title, content FROM course WHERE id = 1 and 1=2 UNION SELECT username, password FROM admin
密码被查询了出来;

Mybatis框架作为一款半自动化的持久层框架,其SQL语句都需要我们自己手动编写,此时就需要我们按照安全编码规范进行开发,以防止SQL注入的产生。
Mybatis框架SQL语句安全的写法(即JDBC预编译模式),可以写为:
select * from course where id=#{id}
这即可避免SQL注入漏洞的产生;

1.SQL注入的例子

案例一:
Select * from course where title like ‘%#{title}%’
由于这样写程序会报错,开发人员会将SQL改为:
Select * from news where title like ‘%${title}%’,
此时程序不再报错,但会产生了SQL语句拼接问题,如果Java代码未对用户输入的内容做处理可能产生SQL注入漏洞。
如果用户输入:%’ AND 1=1AND ‘%’=’
可将SQL查询语句设计如下:
select * from news where tile like concat(‘%’, #{title}, ‘%’)
采用预编译机制,避免SQL语句拼接问题,从根源上防止SQL注入漏洞的产生。

案例二:
select * from news where id in (#{id})
由于这样写程序会报错,开发人员将SQL查询语句修改如下:
Select * from news where id in (${id})
此时便引入了SQL语句拼接的问题,如果研发人员未对用户输入的内容做过滤,容易产生SQL注入漏洞。
uUserInfoMapper.selectByIn(“select user_name from u_user_info”);

where user_name in (${userName})
可使用MyBatis自带循环标签解决SQL语句动态拼接的问题:
select * from news where id in
<foreach collection=“ids” item=“item” open="(“separator=”," close=")">
#{item}

案例三:
Select * from news where title =‘动力节点’ order by ${time} asc,
产生了SQL语句拼接问题,有可能引发SQL注入漏洞。

案例四:
select * from user where ${column} = #{value}
其中 ${column} 会被直接替换,而 #{value} 会被使用 ? 预处理。
User userOfId1 = userMapper.findByColumn(“id”, 1L);
User userOfNameKid = userMapper.findByColumn(“name”, “kid”);
User userOfEmail = userMapper.findByColumn(“email”, “noone@nowhere.com”);
应该怎么做? 制定安全编码规范,不要出现SQL直接替换/拼接的问题,要采用预编译模式;

#{xxx},使用的是PreparedStatement,会有类型转换,所以比较安全;
${xxx},使用字符串拼接,可以SQL注入;
like查询不小心会有漏动,正确写法如下:
Mysql: select * from t_user where name like concat('%', #{name}, '%')      
Oracle: select * from t_user where name like '%' || #{name} || '%'      
SQLServer: select * from t_user where name like '%' + #{name} + '%'

2.MyBatis动态SQL

根据不同条件拼接 SQL 语句是非常痛苦的,拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号,利用动态 SQL 这一特性可以彻底摆脱这种痛苦;
if --判断标签
choose (when, otherwise) --多项选择 ,与页面的 jstl 标签非常类似
trim (where, set) --修剪、格式化,添加前后缀的一个标签
foreach --循环

select * from news where 1 = 1 and title = #{title} and content = #{content} and owner = "zhangsan"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值