Mybatis 混合预处理语句和 sql 注入
Posted
技术标签:
【中文标题】Mybatis 混合预处理语句和 sql 注入【英文标题】:Mybatis mix prepared statement with sql injection 【发布时间】:2021-06-21 12:34:07 【问题描述】:我有一个查询,我希望 Mybatis 将它的一部分视为 sql 注入,也可以视为准备好的语句。我使用的是 Mybatis xml 文件而不是注释。这就是我想要做的......
我的 java 对象正在传递一个包含 processId 和开始和结束日期的参数映射。 processId 是 WHERE 子句之前查询“顶部”的一部分。开始和结束日期在 WHERE 子句中。所以我试图获得作为准备好的语句运行的好处,但直到运行时我才知道 processId。我的 sql 如下所示,但不确定如何将这两种构建 sql 的模式混合在一起。有什么办法可以做到吗?
SELECT $processId, x, y, z FROM AnotherTable t
WHERE t.startDate >= ? AND t.endDate <= ?```
【问题讨论】:
【参考方案1】:我找到了答案。我只需要在我的插入标签中指定参数类型和参数映射属性...
<parameterMap type="java.util.Map" id="myParameterMap">
<parameter property="startDate"/>
<parameter property="endDate"/>
</parameterMap>
<insert id="theSqlToRun" parameterType="java.util.Map" parameterMap="myParameterMap">
SELECT $processId, x, y, z FROM AnotherTable t
WHERE t.startDate >= ? AND t.endDate <= ?
</insert>
【讨论】:
那是因为您决定不命名第二个和第三个参数,而是使用?
(位置参数)。我建议不要这样做(并将它们命名为#startDate
和#endDate
),因为将来修改 SQL 语句时很容易出错。
如doc 中所述,<parameterMap />
已弃用。没有需要它的功能。不清楚processId
在SQL语句中是用作常量值还是列名。如果它是一个常数值,@TheImpaler 的答案是正确的。如果processId
是列名,则@TheImpaler 的上述评论是正确的解决方案。【参考方案2】:
您不需要 SQL 注入(如$a
)。普通参数(如#a
)将起作用。你没有提到具体的数据库,但据我记得所有 JDBC 驱动程序我都在“选择列表”中尝试过支持参数。
你可以这样做:
<select id="mySelect">
select #processId, x, y, z
from AnotherTable t
where t.startDate >= #startDate AND t.endDate <= #endDate
</select>
记得如上所示转义你的<
。
【讨论】:
谢谢穿刺者。看起来我可以使用 $processId 以及 #startDate 和 #endDate 来混合“statement”和“prepared statement”,并按预期工作。 是的,您可以这样做,但除非绝对必要,否则最好避免 SQL 注入。下一个修改应用程序的开发人员可能不会像您那样小心,并且可能会在应用程序中打开一个很大的安全漏洞。以上是关于Mybatis 混合预处理语句和 sql 注入的主要内容,如果未能解决你的问题,请参考以下文章