MyBatis防止SQL注入的方法

1. 前言

    这个问题其实就是问MyBatis中的#{}和KaTeX parse error: Expected 'EOF', got '#' at position 19: …号的区别,在MyBatis中,#̲{}是预编译处理, {}是字符串替换。MyBatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。使用 #{} 可以有效的防止SQL注入,提高系统安全性。

2. 示例


${param}传递的参数会被当成sql语句中的一部分,比如传递表名,字段名
 
例子:(传入值为id)
 
order by ${param} 
 
则解析成的sql为:
 
order by id
 
 
#{parm}传入的数据都当成一个字符串,会对自动传入的数据加一个双引号
 
例子:(传入值为id)
 
select * from table where name = #{param}
 
则解析成的sql为:
 
select * from table where name = "id"
 
为了安全,能用#的地方就用#方式传参,这样可以有效的防止sql注入攻击
 
 
 
sql注入简介
直接上了百度的例子,感觉一看就清晰明了
 
某个网站的登录验证的SQL查询代码为:
 
strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"
 
恶意填入
 
userName = "1' OR '1'='1";
 
与passWord = "1' OR '1'='1";
 
时,将导致原本的SQL字符串被填为
 
strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"
 
也就是实际上运行的SQL命令会变成下面这样的
 
strSQL = "SELECT * FROM users;"
 
这样在后台帐号验证的时候巧妙地绕过了检验,达到无账号密码,亦可登录网站。所以SQL注入攻击被俗称为黑客的填空游戏。

3. 不用MyBatis防止SQL注入的方法

    使用JDBC中的******PreparedStatement******,采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的set方法传值即可。


    使用好处:
  1. 代码的可读性和可维护性.
  2. PreparedStatement尽最大可能提高性能.
  3. 最重要的一点是极大地提高了安全性.

4. 原理

    MyBatis防止SQL注入的原理:MyBatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值 ,PreparedStatement在执行阶段只是把输入串作为数据处理,不再对sql语句进行解析,准备,因此也就避免了sql注入问题。



    PreparedStatement防止SQL注入的原理:JDBC的PreparedStatement会将带’?'占位符的sql语句预先编译好,也就是SQL引擎会预先进行语法分析,产生语法树,生成执行计划。对于占位符输入的参数,无论是什么,都不会影响该SQL语句的语法结构了,因为语法分析已经完成了,即使你后面输入了这些sql命令,也不会被当成sql命令来执行了,只会被当做字符串字面值参数。所以的sql语句预编译可以防御SQL注入。而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。

5. 参考链接

https://blog.csdn.net/qian_qian_123/article/details/92844194
https://www.cnblogs.com/pressur/p/11226392.html
https://blog.csdn.net/weixin_39986856/article/details/83651847


2022年1月6日 阴

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐