12306曝光sql注入漏洞,我试着发布解决方案

在项目中,运用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 
 
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$%'  
 
title like '%$title$%' 
存在SQL注入漏洞。
 
下面是一段单元测试:
 
Java代码
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()) 
[java] view plaincopy
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语句):
 
 
select * from poll   where    title like  '%1231%'  or  '1%'  =  '1%'  
[java] view plaincopy
1. select * from poll   where    title like '%1231%' or '1%' = '1%' 
尽管title 没匹配对,但是or后面那句是恒等的。哎!
 
看来下面的写法只是简单的转义下:
 
 
title  like   '%$title$%'  
 
title like '%$title$%' 
如何解决:
 
在oracle下面改成:title like '%'||#title#||'%',这样肯定是可以的。
 
但是在mysql中,上述写法是不行,还是有上面的问题的:
 
 
select   *  from  poll  where   title  like   '%' ||?|| '%'    order   by  gmt_create  desc    limit ?, ? 
 
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 ?, ?
 
呵呵,多次测试均没有发现问题!