一、在
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#,'%') ;
4、以上只是编码LIKE语句的SQL注入防范,实际中需要对用户输入进行过滤处理;