从orderby引发的SQL注⼊问题的思考
背景:
某⼀天准备上线,合完master之后准备发布了,忽然公司的代码安全监测提⽰了可能在代码中存在sql注⼊的风险,遂即检查,发现sql注⼊问题
既然碰到了这个问题,那就了简单了解下sql注⼊
基础知识:
SQL注⼊基本原理:
所谓SQL注⼊,就是通过把SQL命令插⼊到Web表单提交或输⼊域名或页⾯请求的查询字符串,最终达到欺骗服务器执⾏恶意的SQL命令。
注⼊攻击的本质,是把⽤户输⼊的数据当做代码执⾏。这⾥有两个关键条件,第⼀个是⽤户能够控制输⼊;第⼆个是原本程序要执⾏的代码,拼接了⽤户输⼊的数据。
SQL注⼊类型
按照注⼊点类型来分类
(1).数字型注⼊点(当输⼊的参数为整形时,如果存在注⼊漏洞,可以认为是数字型注⼊。)
sql原型:select*from aaa where id =1,有如下种可能:
1). 加单引号,对应的sql:select*from aaa where id=3’ 这时sql语句出错,程序⽆法正常从数据库中查询出数据,就会抛出异常;
2).加or 1=1,对应的sql: select*from aaa where id=3 or 1=1 这个时候能够查询到所有的结果
3).加上 and 1=1 对应的sql:select*from aaa where id=3and1=1不能查询到结果
(2).字符型注⼊点(当输⼊的参数为字符串时,称为字符型。字符型和数字型最⼤的⼀个区别在于,数字型不需要单引号来闭合,⽽字符串⼀般需要通过单引号来闭合的。)
sql原型:select*from aaa where name='admin',有如下种可能:
1).加单引号:
select * from aaa where name ='admin' and 1=1 -- '
这种注⼊⽅式并不会影响查询结果
2).加union:
select name from aaa where name='1' union select database()#'
这种的结果就是把数据库信息泄露出去。
3).加or
select name from aaa where name='11' or '1234 '='1234'
这种就是导致查询的结果并不是期望的结果,导致数据泄露
(3).搜索型注⼊点(说明⼀下,搜索型注⼊也⽆他,前加%' 后加 and '%'=' 对于MYSQL数据库,后⾯可以吧 and '%'='换成--)
这是⼀类特殊的注⼊类型。这类注⼊主要是指在进⾏数据搜索时没过滤搜索参数,⼀般在链接地址中有“keyword=关键字”,有的不显⽰在的链接地址⾥⾯,⽽是直接通过搜索框表单提交。此类注⼊点提交的 SQL 语句,其原形⼤致为:select * from 表名 where 字段 like '%关键字%'。
按照数据提交的⽅式来分类
(1)GET 注⼊
(2)POST 注⼊
使⽤ POST ⽅式提交数据,注⼊点位置在 POST 数据部分,常发⽣在表单中。
(3)Cookie 注⼊
HTTP 请求的时候会带上客户端的 Cookie, 注⼊点存在 Cookie 当中的某个字段中。
(4)HTTP 头部注⼊
注⼊点在 HTTP 请求头部的某个字段中。⽐如存在 User-Agent 字段中。严格讲的话,Cookie 其实应该也是算头部注⼊的⼀种形式。因为在 HTTP 请求的时候,Cookie 是头部的⼀个字段。
xml实体解析xpath注入按照执⾏效果来分类
(1)基于布尔的盲注,即可以根据返回页⾯判断条件真假的注⼊。
(2)基于时间的盲注,即不能根据页⾯返回内容判断任何信息,⽤条件语句查看时间延迟语句是否执⾏(即页⾯返回时间是否增加)来判断。
(3)基于报错注⼊,即页⾯会返回错误信息,或者把注⼊的语句的结果直接返回在页⾯中。
(4)联合查询注⼊,可以使⽤union的情况下的注⼊。
(5)堆查询注⼊,可以同时执⾏多条语句的执⾏时的注⼊。
基本原理了解了⼀些之后,再来⼀个案例吧
案例:
持久层框架:MyBatis
<dependency>
<groupId&batis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.1</version>
</dependency>
sql内容:
<if test="derBy != null">
ORDER BY ${derBy}
</if>
背景:orderBy使⽤不规范也会引发sql注⼊吗?
例如:
select * from aaa order by id and(updatexml(1,concat(0x7e,(select system_user())),0));
这⾥介绍下:UPDATEXML (XML_document, XPath_string, new_value);
第三个参数:new_value,String格式,替换查到的符合条件的数据
作⽤:改变⽂档中符合条件的节点的值
执⾏上⾯的sql,通过报错内容获取当前连接数据库的⽤户名
[SQL]select * from aaa order by id and(updatexml(1,concat(0x7e,(select system_user())),0));
[Err] 1105 - XPATH syntax error: '~root@localhost'
在mybatis中如何避免?
在mybatis中,#{} 相当于 jdbc中的preparedstatement,就是说传递过来的参数会⾃动加上单引号,⽽${} 是直接输出变量的值。⼀般来说,使⽤#{}语法,MyBatis 会产⽣PreparedStatement语句中,并且安全的设置PreparedStatement参数,这个过程中MyBatis会进⾏必要的安全检查和转义。⽐如这样:
执⾏SQL:Select * from aaa where name = #{name}
参数:aaa
解析后执⾏的SQL:Select * from aaa where name = ?
也就是说#{}更安全⼀些。但是order by 明显是不能使⽤这种⽅式的。order by 之后如果使⽤ #{} 使⽤时则变成了 order by '...' 那么sql就直接报错了避免该种类型的sql注⼊的有效措施就是在程序中判断排序字段以保证xml中只可能出现某些情况或者在xml中固定排序字段
Mybatis中其他易产⽣SQL注⼊的场景
模糊查询 like
正常程序:select*from aaa where name like'%${likeColumn}%'可能会存在sql注⼊问题
修改后:
select * from aaa where name like concat('%',#{likeColumn},'%')
修改点:从 ${} 改为 #{},从sql拼接到 concat⽅式
in之后的参数
正常程序:Select*from aaa where id in (${id})
修改后:
select * from aaa where id in
<foreach collection="ids" item="item" open="("separator="," close=")">#{item} </foreach>
ok,先简单对sql注⼊有个了解。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论