[英]Prepared Statement effect against SQL Injection
例如,我有以下代碼:
import java.sql.*; ...
public void main (string[] args){
try {
Class.forName („COM.ibm.db2.jdbc.net.DB2Driver“);} catch (ClassNotFoundException e) {//error handling}
try {
String url = "jdbc:db2://host:6789/myDB2"
Connection con = DriverManager.getConnection(url, "login", "password");
PreparedStatement pStmt = con.prepareStatement("UPDATE PERS SET Salary=Salary*2.0 WHERE PNR=?"
pStmt.setInt (1, 35);
pStmt.executeUpdate();
pStmt.setString (1, args[0]);
pStmt.executeUpdate();
con.close();
} catch (SQLException e) { //error handling}
}
大概我們有這樣的表:
+--------+----------+-----------+
|PNR |Name |Salary |
+--------+----------+-----------+
|34 |Tim |20000 |
+--------+----------+-----------+
|35 |John |45000 |
+--------+----------+-----------+
我很難預測在以下情況下會發生什么情況:
args[0]="35 OR Salary<100000"
setString
命令不是用35 OR Salary < 100000
代替args[0]
,然后所有薪水記錄都翻倍了嗎?
那不會導致SQL注入問題。 它將轉換為:
UPDATE PERS SET Salary=Salary*2.0 WHERE PNR='35 OR Salary<100000'
插入的引號將使您免於SQL注入。 我在簡化一點。 JDBC實現確定PreparedStatement
轉換為實際SQL查詢的精確程度。 它不一定實際將其轉換為上述SQL。 但這是它可以防止攻擊的一種方法。
不過要小心。 如果使用用戶輸入來創建SQL,則仍然容易受到SQL注入的影響。 只要您僅使用用戶輸入來調用.setXYZ()
參數,就可以放心使用。
SQL參數有助於避免SQL注入,因為該參數的值根本沒有與SQL查詢結合。 帶有參數占位符的SQL查詢將發送到MySQL服務器,在此進行解析和分析。 它執行的操作類似於檢查您是否編寫了有效的SQL語法,所引用的表和列是否存在以及是否具有訪問這些表和列的正確權限。
這就是為什么參數不能用於表名或列名或其他語法的原因。 因為驗證是在參數仍保留為占位符時發生的。 參數的值稍后發送,因此驗證必須假定參數必須替換SQL查詢中的單個標量值。
此后,查詢將作為非文本數據結構內部存儲在MySQL服務器中。 它不再在SQL中使用,它只是MySQL代碼中的許多內部對象。 您曾經使用過的地方?
成為MySQL知道可以執行查詢之前需要提供值的查詢元素。
運行pStmt.executeUpdate()
,綁定到參數的變量的值將發送到MySQL服務器。 它們以查詢的非文本表示形式填充到占位符中。
這樣,直到解析完成后,才將參數值組合在一起,因此,參數內容無法更改SQL語法。 它只會像單個字符串那樣影響SQL查詢,就好像存在一種引號定界符,該類型不能用參數內容中不匹配的引號字符來破壞。
查詢參數是防止SQL注入的可靠方法。
一些驅動程序執行“模擬”准備好的語句。 這意味着除了將SQL字符串保存在JDBC驅動程序中(在客戶端上prepareStatement()
之外,它不會對傳遞給prepareStatement()
的SQL查詢執行任何操作。 它此時不將SQL查詢發送到服務器。
然后,當您運行executeUpdate()
時, executeUpdate()
變量插入到SQL字符串中的參數占位符中,並將完整的字符串發送到服務器。 然后,MySQL服務器使用參數值和全部解析組合的SQL查詢。 MySQL Server甚至無法分辨出哪些值是原始SQL查詢中的文字值,以及哪些組合為參數。 它們全都顯示為解析器的文字值。
在這種情況下,您必須相信JDBC驅動程序可以正確地進行轉義,因此參數內容中的引號和其他字符不會混淆SQL解析器。 應該對驅動程序進行充分的測試,以處理所有情況,例如特殊字符集和十六進制編碼的引號字符以及其他欺騙方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.