SQL注入
以下面的代码为例:
我们假设下面的语句执行后返回的row不为空则为登陆成功
Statement statement= connection.createStatement();
statement.executeQuery("select * from accounts where username='"+username+"' and password='" + password+"'");
username 和 password 是读取用户输入的string 变量
这个时候,假设用户输入的用户名是
a
password是
' or 'a'='a
此时语句就会变成
select * from accounts where username='a' and password='' or 'a'='a'
这个时候,由于sql逻辑运算符的特性,运算逻辑是这样的
select * from accounts where (username='a' and password='') or ('a'='a')
注:这是不符合语法的,只是方便理解
所以,在这种情况下,无论你用户名输入的是什么,都会返回整个列表,也就是,都能登陆成功
这就是SQL注入
解决方法
使用PreparedStatement代替Statement
把上面的代码替换成:
// ?代表预留占位符
String query="select * from accounts where username=? and password=?";
// 把query预编译,占位符等待参数注入
// 我的理解是:
// 与直接执行不同的是,通过预编译,保存了语句结构
// 无论后面占位符注入的是什么,都不会改变这个结构(不会增加判断条件),只会为结构内的col筛选条件赋值
PreparedStatement psm= connection.prepareStatement(query);
// 赋值占位符, 第一个参数代表占位符位置
psm.setString(1,username);
psm.setString(2,password);
// 执行
psm.executeQuery();
这样就可以解决SQL注入