一、在
iBatis或者myBatis模糊查询的LIKE语句避免采用如下写法,否则会导致SQL注入;
- <select id="INSTITUTIONS-GET-PARAMS" resultMap="INSTITUTIONSDO-MAP" parameterClass="java.util.Map">
- <![CDATA[
- SELECT /*INSTITUTIONS-CLASSIFICATION-GET-ALL-COUNT */
- i.id,
- i.institution_name,
- i.institution_short_name,
- i.create_time,
- i.agency_headquarters,
- i.registration_site,
- i.website_url,
- i.brief_introduction,
- i.logo_url,
- i.hot
- FROM ins i
- ]]>
- <isNotEmpty property="categoryCode">
- LEFT JOIN ins_industry ii
- ON i.id = ii.institutionId
- LEFT JOIN ind_type it
- ON it.id = ii.typeId
- </isNotEmpty>
- where 1=1
- <dynamic>
- <isNotEmpty property="categoryCode" prepend=" AND ">
- <![CDATA[
- it.category_code = #categoryCode#
- ]]>
- </isNotEmpty>
- <isNotEmpty property="institutionName" prepend=" AND ">
- i.institution_short_name LIKE '%$institutionName$%'
- </isNotEmpty>
- ORDER BY i.hot ASC
- <isNotEmpty property="start">
- LIMIT #start#,
- <isNotEmpty property="size">
- #size#
- </isNotEmpty>
- </isNotEmpty>
- </dynamic>
- </select>
如上SQL语句,如果用户输入:
%' AND 2498=2498 AND '%'=',会构成如下SQL,精简后如下,是能正确返回记录的,即存在SQL注入:
- SELECT
- i.id,
- i.institution_name,
- i.institution_short_name,
- i.create_time,
- i.agency_headquarters,
- i.registration_site,
- i.website_url,
- i.brief_introduction,
- i.logo_url,
- i.hot
- FROM ins i
- LEFT JOIN ins_industry ii
- ON i.id = ii.institutionId
- LEFT JOIN ind_type it
- ON it.id = ii.typeId
- where 1=1 AND
- i.institution_short_name LIKE '%%' AND 2498=2498 AND '%'='%'
- ORDER BY i.hot ASC LIMIT 0, 10
二、解决办法:
1、尽量避免采用$的方式,$会导致SQL注入,
LIKE '%$institutionName$%' 和
LIKE
concat(
'%',$institutionName$,'%') 都会导致SQL注入
;
2、尽量采用
#的方式,#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号;
更详细的可以查看$和#的区别;
3、对于例子中的模糊查询,
可以用#结合
concat函数,即修改为
LIKE concat('%',#institutionName#,'%') ;也可以
可以将LIKE '%${Name}%'修改为LIKE '%'||#{Name}||'%'
4、以上只是编码LIKE语句的SQL注入防范,实际中需要对用户输入进行过滤处理;