一、什么是SQL注入?
所谓SQL注入就是有些相关专业人员,可能懂这方面的专业知识,会根据我们后端写的一些sql语句进行相应的字符集输入,而输入的这些字符集就可能会导致我们的系统被攻击,其本质就是通过sql从而骗取数据库执行的那些sql语句。
相关示例:(用户登录)
假设我们后端现在有这样的一条sql:
String allUser = "select * from users where username = ' " + username + " ' and password = ' " + password + " ' ";
上面这条sql是基于字符串拼接的方式去进行书写的,如果我们的username和password输入了sql相关的非法字符集就会有可能导致用户直接查询成功,假设用户在前端输入了如下用户名和密码:
username: ' or ' 1 ' = ' 1 ' --
password: 随便输入
由于username 输入了一个or语句所以只要条件中一个为真那么就可以直接返回用户信息了,1肯定是永远都等于1的,至于password是否还看,其实是不用看的,--注释已经将后面的语句注释了。
二、防止SQL注入
2.1 原生JDBC防止sql注入的方式
使用PreparedStatement,当一条sql语句去被执行时,预编译中的?占位符,会将传递的参数作为数据进行赋值,而不是作为一条sql中的某个部分去执行。
列如上面输入的username= ' or ' 1 ' = ' 1 ' --,如果使用预编译sql,这个时候就会将输入的这一串字符当作username为 ' or ' 1 ' = ' 1 ' --的用户名,按照这个用户名去查找。
2.2 Mybatis框架处理
像Mybatis这样的ORM框架提供了解决SQL注入的方法,通常写的最多的就是#{}占位符,这个符号就是用来处理预编译的,与之相对应的是${}占位符,如果使用${}可能会造成SQL注入,因为${}就有点像我们之前写的字符串拼接sql。
select username from users wherer username = #{username}
上面的username就会被解析成 ? ,并且设定为参数值,不进行拼接sql,如果是${},就直接替换。
2.3 正则表达式
利用正则表达式去限制用户可能输入的非法字符集
String userInput = "username";
if (userInput.matches ("[a-zA-Z0-9]+$"))
{
System.out.println("输入合法");
}
else {
System.out.println("非法");
}