SQL注入与Statement缺点 作者:马育民 • 2022-01-13 16:29 • 阅读:10061 # 说明 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注入** 的问题 原文出处:http://malaoshi.top/show_1IX2aMXBCjLn.html