2014-08-30 74 views
-4

大家都知道,PDO準備語句可以幫助我們防止SQL注入攻擊。這個怎麼樣:普通mysql準備語句防止注入攻擊?

function userQuery($username){ 
    $mysqli->multi_query(" 
     PREPARE stmt1 FROM 'SELECT * FROM user WHERE username=?'; 
     SET @a = '$username'; 
     EXECUTE stmt1 USING @a 
    "); 
} 
userQuery('Kelvin'); 

這是像mysqli或PDO準備聲明一樣安全嗎?

我問這個問題,因爲我發現這些句子上wiki

預處理語句是對SQL注入彈性,因爲參數值,它們使用不同的協議進行傳送,不需要正確轉義。如果原始語句模板不是從外部輸入派生的,則SQL注入不會發生。

他們提到約parameters are transmitted later with different protocol。我並不真正瞭解 這個。

parameters are transmitted later with different protocol如何防止注射攻擊?

+2

請考慮**注射攻擊是如何工作的,然後將相同的邏輯應用於上述場景。 – 2014-08-30 10:34:38

+0

我已更新我的問題。請讓我知道如果我仍然在某個地方錯了。 – user3925697 2014-08-30 10:47:09

回答

2

[我假設你的意思$ mysqli的是mysqli的連接。]

雖然stmt1的執行(最後的三個查詢)是安全的,你寫的多查詢功能是非常不安全的。運行類似

userQuery("'; delete from user; select * from user where username='"); 

實際上會從您的用戶表中刪除所有用戶。假設$ username表示沒有正確轉義的原始用戶輸入,後果可能是災難性的。

你可以使用mysqli :: real_escape_string來改進上面的內容並自己進行轉義,但是有很多更復雜的方法可以完成上面的黑客攻擊。準備好的陳述都是更好的解決方案。

+0

感謝您的回答。順便說一句,你的意思是說,如果我把我的多個查詢分開到單獨的查詢將是安全的? – user3925697 2014-08-30 11:04:08

+0

如果你這樣做(不知道這是否會工作),你的設置@a = ...仍然會有相同的屬性。如果你想使用mysqli安全地執行此操作,請查看以下答案:[如何在PHP中創建安全的準備mysql語句?](http://stackoverflow.com/questions/1290975/how-to-create-a-保護MySQL的準備語句功能於PHP)。 – vch 2014-08-30 23:26:07

+0

至於你的問題更新:準備報表的工作方式與正常報表的工作方式略有不同。與你的查詢一起被傳送到服務器以及由你注入的參數,然後被編譯,執行和丟棄,你的預處理語句查詢首先被傳送到帶有參數佔位符的服務器。它有編譯,只有參數佔位符。這個聲明然後準備好執行。在執行時,參數值被注入到已編譯的查詢中,所以像我向你演示的那些技巧將不起作用。 – vch 2014-08-30 23:41:09