话说回来,是否我们使用MyBatis就一定可以防止SQL注入呢?当然不是,请看下面的代码:
<select id="getBlogById" resultType="Blog" parameterType=”int”> SELECT id,title,author,content FROM blog WHERE id=${id} </select>
仔细观察,内联参数
的格式由“#{xxx}”
变为了“${xxx}”
。如果我们给参数“id”
赋值为“3”
,将SQL打印出来是这样的:
SELECT id,title,author,content FROM blog WHERE id = 3
(上面的对比示例是我自己添加的,为了与前面的示例形成鲜明的对比。)
<select id="orderBlog" resultType="Blog" parameterType=”map”> SELECT id,title,author,content FROM blog ORDER BY ${orderParam} </select>
仔细观察,内联参数
的格式由“#{xxx}”
变为了“${xxx}”
。如果我们给参数“orderParam”
赋值为“id”
,将SQL打印出来是这样的:
SELECT id,title,author,content FROM blog ORDER BY id
显然,这样是无法阻止SQL注入
的。在MyBatis中,“${xxx}”
这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”
这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。
【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”
这样的格式。若不得不使用“${xxx}”
这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。
#{}:相当于JDBC中的PreparedStatement
${}:是输出变量的值
简单说,#{}
是经过预编译
的,是安全
的;${}
是未经过预编译
的,仅仅是取变量的值,是非安全的
,存在SQL注入。
如果我们order by
语句后用了${}
,那么不做任何处理的时候是存在SQL注入危险
的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。
到此这篇关于MyBatis中防止SQL注入的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。
更多SQL内容来自木庄网络博客