SQL注入小结
- 一:什么是SQL注入
- 二:SQL注入攻击实例
- 三:如何防御SQL注入
- 1. 检查变量的数据格式和数据类型
- 2. 过滤特殊字符
- 3. 使用预编译功能
- 四:什么是预编译
- 五:MyBatis怎么防范SQL注入
- 1.mybatis中的#和$的区别:
- 2.mybatis是如何做到防止sql注入的:
一:什么是SQL注入
SQL注入是一种网络上常见的攻击方式,是通过对程序员编写代码疏忽进行攻击的,通常通过SQL语句来实现无账号登录等操作.
二:SQL注入攻击实例
String sql = "select * from user_table where username = '"+userName+"' and password = '"+password+"' ";
如上代码,该语句输入了账号userName和密码password后就会变成如下:
select * from user_table WHERE username= '' or 1 = 1 -- and password = '';
分析: 条件后面username= ‘’ or 1 = 1,这个一定会成功,再则后面的两个-,直接注释掉了password = ''的部分,导致该语句永远能够正常执行,所以能够轻易的绕过系统校验.
三:如何防御SQL注入
坚持"外部数据不可信任"原则
1. 检查变量的数据格式和数据类型
只要是有固定格式的变量,在SQL语句执行前,应该严格按照固定格式去检查,确保变量是我们预想的格式,这样很大程度上可以避免SQL注入攻击.
不过,仍然有很多例外情况并不能应用到这一准则,比如文章发布系统,评论系统等必须要允许用户提交任意字符串的场景,这就需要采用过滤等其他方案了.
2. 过滤特殊字符
对于无法确定格式的变量,一定要进行特殊字符的过滤和转义
3. 使用预编译功能
mysql有驱动能够提供预编译功能,实际上,绑定变量使用预编译语句是预防SQL注入的最佳方式,使用预编译的SQL语句语义不会发生改变,在SQL语句中,变量用问号?表示,黑客即使本事再大,也无法改变SQL语句的结构.
四:什么是预编译
所谓预编译语句就是将这类语句中的值用占位符替代,可以视为将sql语句模板化或者说参数化.总的来说就是"一次编译,多次运行.,省去了解析优化等过程
注意**MySQL的老版本(4.1之前)**是不支持服务端预编译的,但基于目前业界生产环境普遍情况,基本可以认为MySQL支持服务端预编译.
MySQL中的预编译语句作用域是session级,但我们可以通过max_prepared_stmt_count变量来控制全局最大的存储的预编译语句.
五:MyBatis怎么防范SQL注入
1.mybatis中的#和$的区别:
- #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.
- $将传入的数据直接显示生成在sql中
- 所以#方式能够很大程度防止sql注入,而$方式无法防止sql注入
- $方式一般用于传入数据库对象,例如传入表名
- 一般能用#的就别用{xxx}”这样的参数(例如涉及到动态表名和列名时),要手工地做好过滤工作,防止SQL注入
2.mybatis是如何做到防止sql注入的:
mybatis是一款半自动化的持久层框架,sql是要我们自己写的,所以需要防范SQL注入,parameterType表示了输入的参数类型,resultType表示了输出的参数类型,如果我们想防止SQL注入,应该从参数上入手,代码中用#的即输入参数在SQL中拼接的部分,
传入参数后,打印出执行的SQL语句,会看到SQL是这样的:
select id, username, password, role from user where username=? and password=?
这是因为MyBatis启用了预编译功能,在SQL执行前,会将上面的SQL发给数据库进行编译,执行时直接用编译好的SQL替换占位符?就可以了,因为SQL注入只对编译过程起作用,所以这种方式就很好的防范了SQL注入问题.