说明
SQL注入,一般用于 破解登录,即:不知道用户名、密码的情况下,进行登录
MySQL 注入原理
会被注入的 SQL,是将 用户名、密码 拼接 到 SQL中,如下:
String sql="select * from user where username='"+username+"' and password='"+password+"' ";
正常用户名、密码
当输入 正常 的用户名、密码,如:用户名:lilei,密码:123456,拼接结果如下:
select * from user where username='lilei' and password='123456'
是正确的
SQL注入
SQL注入的方式:用户名写 ' or 1=1 #,密码写不写都行,拼接结果如下:
select * from user where username='' or 1=1 #' and password=''
解释:
- 用户名开始的
',与 sql中的'匹配 - 最后的
#号,在 mysql 数据库中,表示 注释 - 由于有
or 1=1,那么一定能够查询出结果
代码演示
使用 JDBC的 Statement,就会发生 SQL注入
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class SQL注入 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
String url = "jdbc:mysql://127.0.0.1:3308/scott?useSSL=false";
// 正常的用户名、密码
// String username = "lilei";
// String password = "123456";
// sql注入
String username = "' or 1=1 #";
String password = "";
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, "root", "");
Statement stmt = conn.createStatement();
String sql = "SELECT * FROM USER WHERE username='" + username + "' and password='"+ password + "'";
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
if (rs.next()) {
String id = rs.getString(1);
Object name = rs.getObject(2);
Object passowrd = rs.getObject(3);
System.out.println("登录成功!");
System.out.println(id + "," + name + "," + passowrd);
} else {// 没有查询到此用户、密码,说明登录失败
System.out.println("输入用户名或密码错误,请重新输入!");
}
conn.close();
}
}
解决
采用 JDBC PreparedStatement 占位符 的方式,可以很好的避免 SQL注入 的问题