我有一个搜索页面,该页面使用用户的输入术语查询数据库。我使用Mybatis 3.4.0带有弹簧。
问题是Mybatis在搜索词中删除了任何单个引号,无论我是否逃脱。这些是有效的查询,因为用户需要能够搜索诸如O'Toole之类的字符串,但是什么都没有返回。
这是映射器中代码的片段。所讨论的字段是caseWhereConditionDTO.value
,并且输入值是例如O''TOOLE
(代码中手动逃脱了先验(
<if test="caseWhereConditionDTO.value != null">
${caseWhereConditionDTO.leftExpression}
${caseWhereConditionDTO.operator}
#{caseWhereConditionDTO.value}
${caseWhereConditionDTO.closeConditionString}
</if>
导致Where子句
where UPPER(p.last_name ||', ' || p.first_name ) LIKE 'OTOOLE%'
缺少双重逃脱的O''Toole
在映射器中,我用$替换#并用单个引号
替换#时一切正常'${caseWhereConditionDTO.value}'
导致
的SQL输出where UPPER(p.last_name ||', ' || p.first_name ) LIKE 'O''TOOLE%'
给出预期查询结果
但是,我当然要保留#{}
的SQL注入保护所以我的问题是,在仍使用#{}/准备好的语句的SQL注入保护时,我该如何查询单引号?
有2个选项,无需逃脱单引号:
-
除非确定输入不包含任何
%
,必须先逃脱(如果它们存在于输入中并且不逃脱,则会对SQL造成混乱:是输入的%
一部分还是" 运算符"?(然后将%
与值相连:value = value + "%";
,然后将LIKE #{value}
。 -
更好的选择是仅在SQL查询中加入
%
:LIKE #{value} || '%'
。它确实有效,我只是重新检查了。