Statement操作sql語句的弊端
Statement操作SQL語句的弊端
在學習JDBC的時候,提到了用Statement進行資料庫的增刪改查的弊端,主要有兩點。
- 拼寫sql語句涉及字串的拼接,太痛苦
- sql注入
. 下面通過一個登入情景說明這兩個弊端
登入的過程:
簡單的登入實現,使用者輸入使用者名稱和密碼。獲取使用者名稱和密碼的資訊後去資料庫的表中對比,如果發現有匹配的使用者名稱和密碼,就表明登入成功,沒有匹配的使用者資訊說明匹配失敗。
我寫了一個get方法,該方法可以去資料表中檢視是否有對應的使用者資訊,如果有就返回相應的User物件,沒有則返回null
get方法程式碼:
public static User get(String sql) throws Exception{
//獲取基本的配置資訊
InputStream input=StatementCase.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pro=new Properties();
pro.load(input);
String url=pro.getProperty("url");
String user=pro.getProperty ("user");
String password=pro.getProperty("password");
String driverClass=pro.getProperty("driverClass");
//載入驅動類
Class.forName(driverClass);
//獲取連線
Connection con=DriverManager.getConnection(url,user,password);
Statement statement=con.createStatement ();
ResultSet rs=statement.executeQuery(sql);
User login_user=null;
if(rs.next()){
String username=rs.getString("username");
String password1=rs.getString("password");
login_user=new User();
login_user.setUsername(username);
login_user.setPassword(password1);
}
return login_user;
}
使用者輸入使用者名稱,密碼
public static void main(String[] args) throws Exception {
Scanner scanner=new Scanner(System.in);
System.out.print("使用者名稱:");
String user=scanner.next();
System.out.print("密碼:");
String password=scanner.next();
String sql="select username,password from userinfo where username='"+user+"' and password= '"+password+"'";
User result=get(sql);
if(result!=null){
System.out.println("登入成功");
}
else{
System.out.println("登入失敗");
}
}
目前為止看起來都一切良好,這個時候問題來了,我必須把變數名user,password放進我的sql語句中去。也就是這個樣子:
select username,password from userinfo where username='變數user' and password= '變數password'
由於在java中執行的SQL語句必須以字串的形式書寫,那麼就涉及到字串的拼接,就會變成這個樣子
String sql="select username,password from userinfo where username='"+user+"' and password= '"+password+"'";
此時此刻是不是感覺可讀性很差而且寫起來很麻煩,不過都還好,畢竟我們不怕麻煩 (逃
另一個問題卻是我們不能接受的,也就是這篇的重點SQL注入
SQL注入是什麼?
用一個很簡單的例子在理解,我們來看這樣一條SQL語句
SELECT username,
password FROM userinfo WHERE username='a' OR 1 = ' AND password =
' OR '1' = '1'
解析起來就是,篩選username,password欄位,從userinfo這個表中,篩選條件是 XXX or XXX or XXX,這三個XXX只要有一個成立,就表明符合篩選要求。又因為1=1這個條件是恆成立的,所以每一行資料都符合要求,必然可以篩選出結果。
執行結果如下:
於是神奇的地方來了,我可以想辦法在輸入使用者名稱和密碼的時候,輸入一些SQL語句。
然後 , user變數的值就是:a’ OR 1 =
password變數的值就是:OR ‘1’ = '1
導致的結果就是SQL語句會變成我剛剛寫的那個樣子,然後該使用者就登入成功了,這就是SQL注入了。
總結起來SQL注入就是指:由於使用者的惡意輸入,導致系統執行了惡意SQL語句,做一些壞的事情。
小結:
- Statement物件進行增刪改查的時候,需要用字串的拼接寫sql語句,非常麻煩可讀性差
- 由於需要用字串拼接的方式寫sql,所以才給 SQL注入 提供了可乘之機。