在项目中,运用Ibatis中Like写法,没有研究下,结果SQL语句存在SQL注入漏洞,整理下,下次谨记啊!
sql语句:
select * from (select 1 from poll <dynamic prepend=" where "> <isNotEmpty prepend=" and " property="title"> title like '%$title$%' </isNotEmpty> <isNotEmpty property="used"> <isEqual compareValue="true" prepend=" and " property="used"> <![CDATA[status & 2 > 0 and status & 1 <= 0 and status & 8 <= 0 ]]> </isEqual> </isNotEmpty> <isNotEmpty prepend=" and " property="startTimeBegin"> <![CDATA[ gmt_create >= #startTimeBegin# ]]> </isNotEmpty> <isNotEmpty prepend=" and " property="startTimeEnd"> <![CDATA[ gmt_create <= #startTimeEnd# ]]> </isNotEmpty> </dynamic> limit 10000 ) as t
请关注此写法的:
title like '%$title$%'
存在SQL注入漏洞。
下面是一段单元测试:
PollQuery query = new PollQuery(); query.setCurrentPage(1); query.setPageSize(50); query.setTitle("1231%' or '1%' = '1");//很简单的写法:( List<SnsPollDO> l = pollDAO.findPollList(query); System.out.println(l.size())
测试结果(打印处的sql语句):
1. select * from poll where title like '%1231%' or '1%' = '1%'
尽管 title 没匹配对,但是or后面那句是恒等的。哎!
看来下面的写法只是简单的转义下:
title like '%$title$%'
如何解决:
在oracle下面改成:title like '%'||#title#||'%',这样肯定是可以的。
但是在mysql中,上述写法是不行,还是有上面的问题的:
select * from poll where title like '%'||?||'%' order by gmt_create desc limit ?, ?
还能查出结果来!哎!
得用:title CONCAT('%',#title#,'%')
select * from poll where title like CONCAT('%',?,'%') order by gmt_create desc limit ?, ?
呵呵,多次测试均没有发现问题!