SQL註入與防止及myBaits基本作用
SQL註入
在嵌入式SQL編程中,sql語句通常是以字符串的形式提交給數據庫管理系統的。SQL註入是利用SQL語法將一些惡意代碼加入到該字符串中,從而獲取到非授權的數據。
如:用戶登錄(假設用戶名為admin,密碼為 123456),通常使用以下語句進行判斷
select * from user where username=‘admin' and password=‘123456'
如果獲取到記錄,則允許登錄,否則提示“用戶名不存在或密碼錯誤”。加入我並不知道用戶密碼,知道用戶名為“admin”,在輸入用戶名時,將用戶名變為 admin‘– ,此時sql語句變為
select * from user where username=‘admin'-- and password=‘123456'
則登錄成功。如下圖密碼隨意輸入,如果沒有做任何防止SQL註入的處理,完全可以登錄成功
假如:用戶名我輸入的是“admin;drop table user;–”;會發生啥結果?
防止SQL註入的方法
JDBC提供的PreparedStatement可以防止SQL註入;PreparedStatement對sql預編譯後,sql語句中的參數需要用?代替。然後調用setXX()方法設置sql語句中的參數。這樣再傳入特殊值,也不會出現sql註入的問題瞭,示例代碼如下:
String sql="select * from user where username='?'"+" and password='?'"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1,"admin"); pstmt.setString(2,"123456"); //5、執行語句 ResultSet rs=pstmt.executeQuery(sql);
還有另外一種方法,就是把SQL語句寫入存儲過程,通過存儲過程完成查詢,同樣可以防止SQL註入。
mybaits中${}和#{}的使用
“$ ”是拼接符;使用“${} ”相當於在高級語言中已經將sql語句進行拼接,而且對於變量是不加引號的,如:用戶名為admin,參數變量為 sname
select * from user where username=‘${sname}' --此種情況下,高級語言交給數據庫的SQL語句是 select * from user where username=‘admin'
此種情況下是無法防止SQL註入的。
#{}是占位符;使用“#{} ”隻能在數據庫管理系統中,將#{}中的參數帶入
select * from user where username=#{sname} --此種情況下,首先經過預編譯形成如下SQL,再將參數帶入,此時給參數值帶加單引號 select * from user where username=?
此種情況下是可以防止SQL註入的
既然#{}能夠防止SQL註入,”$ {}”不能,為什麼mybaits還要提供這麼一個符號?,當然有myBatis的理由,如果SQL語句中數據庫對象需要傳參進去,那隻能使用** ${}**。如查詢用戶表(user) ,參數變量為tableName=‘user’,代碼隻能是
select * from ${tableName} //轉換為SQL語句為 select * from user
在myBatis中變量做為where子句中的參數,一律使用#{},禁止使用“ ” , 以 防 S Q L 註 入 ; S Q L 語 句 中 包 含 瞭 數 據 庫 對 象 ( 如 表 、 視 圖 等 ) 才 能 使 用 “ {} ”,以防SQL註入;SQL語句中包含瞭數據庫對象(如表、視圖等)才能使用“ ”,以防SQL註入;SQL語句中包含瞭數據庫對象(如表、視圖等)才能使用“{} ”,因為#{},自動給變量加上引號,如上例:
select * from #{tableName} //轉換為SQL語句為 select * from 'user'
以上就是SQL註入與防止及myBaits基本作用的詳細內容,更多關於SQL註入與防止及myBaits作用的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Mybatis是這樣防止sql註入的
- Java JDBC批量執行executeBatch方法詳解
- 實例介紹SQL註入以及如何解決
- Java中JDBC的使用教程詳解
- Java原生操作JDBC連接以及原理詳解