2010-06-23 95 views
6

我目前使用mysqli php擴展。mysqli編寫語句和mysqli_real_escape_string

傳統上我使用mysqli_real_escape_string來轉義用戶輸入。不過,我正在考慮更改代碼(希望儘可能少的步驟)以使用預準備語句。

我想澄清一下 - 只要我使用準備好的語句來綁定我所有的變量,我可以確信sql注入是不可能的嗎? (以及mysqli_real_escape_string完全放棄?)

感謝

回答

5

如果正確綁定所有的變量,你可以大大減少SQL注入的風險。它仍然是可能的,如果你動態地創建SQL例如獲得一個SQL注入:

'SELECT * FROM ' . $tablename . ' WHERE id = ?' 

但是,如果你避免這樣的事情是不可能的,你將有問題。

+0

是,請參閱http://www.sjmp.de/php/php-mysql-mehr-sicherheit-und-erhoehte-performance-durch-mysqli-und-prepared-statements/瞭解更多信息 – Tobias 2011-03-09 10:21:42

4

說到安全性,如果您正確綁定或格式化變量,兩種方法之間沒有區別。

綁定只是簡單的,因爲它可以用於任何情況,而逃避不能(因此,你必須投下一些變量,而不是轉義/引用)。

另外,請記住,沒有綁定或轉義可以使標識符安全。因此,如果您必須在查詢中使用字段名稱或運算符,則必須使用在您的腳本中硬編碼的值。

2

這是我對該主題的高級視圖。

使用動態SQL字符串時,您依賴的轉義函數正常工作。不幸的是,這並非總是如此,因爲在這個(公認歲)的例子可以看出:

http://dev.mysql.com/doc/refman/5.0/en/news-5-0-22.html

一旦你的數據值已經越獄,SQL字符串已經被解析和數據庫編譯服務器。如果轉義函數沒有正常完成其工作,或發現了新的SQL注入攻擊,那麼服務器可能會將數據誤認爲是SQL語句。

如果使用帶有參數的預準備語句,則首先分析並編譯語句。數據值在執行時與編譯語句組合在一起。這將SQL邏輯從數據值中分離出來 - 有機會混淆兩個應該不會出現

所以,是的,你可以免除mysqli_real_escape_string,但我不會說使用帶參數的預準備語句使SQL注入變得不可能。這使得它變得更加困難,但是如同mysqli_real_escape_string的錯誤,我想總有一個機會,一個尚未被發現(或新創建)的bug會使這個看起來不可能的,可能的。