解決 SQL 注入
阿新 • • 發佈:2021-01-09
SQL
注入是什麼?
看一下百度百科的定義:
啊,好長一大段文字,些許不想看,下面通過一個例子,來說明一下什麼是SQL注入
:
新建一個數據庫,再建一個表,新增兩行資料:
use db1;
create table user(
id int primary key auto_increment,
username varchar(32),
password varchar(32)
);
insert into user values(null,'zhangsan','123');
insert into user values(null,'lisi','234');
表如下圖所示:
再隨隨便便用
JDBC
寫個登陸操作:
package com.wzq.jdbc; import com.wzq.util.JDBCUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; /* * 需求: * 1、通過鍵盤錄入使用者名稱和密碼 * 2、判斷使用者是否登陸成功 * */ public class JDBCDemo05 { public static void main(String[] args) { Scanner cin = new Scanner(System.in); System.out.println("請輸入使用者名稱:"); String username = cin.nextLine(); System.out.println("請輸入密碼:"); String password = cin.nextLine(); boolean res = new JDBCDemo05().login(username, password); if (res) System.out.println("登陸成功!"); else System.out.println("登陸失敗!"); } public boolean login(String username, String password) { if (username == null || password == null) { return false; } Connection conn = null; Statement stmt = null; ResultSet rs = null; try { //1、獲取資料庫連線 conn = JDBCUtils.getConnection(); //JDBCUtils工具類 //2、定義sql String sql = "select * from user where username = '" + username + "' and password = '" + password + "'"; //3、獲取執行sql的物件 stmt = conn.createStatement(); //4、執行sql rs = stmt.executeQuery(sql); return rs.next(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.close(rs, stmt, conn); } return false; } }
測試一下:
可以看到,普通的檢驗沒有任何問題,現在使用SQL注入
:
賬戶名稱隨便輸入,密碼輸入:a' or 'a'='a
驚訝的發現,居然登陸成功了。輸出一下sql
看一下:
select * from user where username = 'askjdhjksahd' and password = 'a' or 'a' = 'a'
可以看到where
之後的條件,無論是什麼結果都為真,都會輸出整個表:
所以,綜上所述:在sql
拼接時,有一些sql
的特殊關鍵字參與字串的拼接,就會造成安全性問題,這就是上面為什麼能登陸成功的原因所在。
那怎麼解決這個問題呢?
答:利用PreparedStatement
Statement
物件。
PreparedStatement
物件是Statement
物件的子類,它是預編譯的sql
,所以執行速度會比Statemnet
更快。
PerpaerdStatement
使用?
作為佔位符,使用setXxx(索引,值)
給?
賦值
所以我們替換一下Statement
,寫一下程式碼:
public boolean login(String username, String password) {
if (username == null || password == null) {
return false;
}
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
//1、獲取資料庫連線
conn = JDBCUtils.getConnection(); //JDBCUtils類
//2、定義sql
String sql = "select * from user where username = ? and password = ?";
//3、獲取執行sql的物件
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,username);
pstmt.setString(2,password);
//4、執行sql
rs = pstmt.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, pstmt, conn);
}
return false;
}
測試一下:
成功解決!