2014-01-12 122 views
2

我一直在忙着使用我的PHP代碼和SQL語句,雖然我知道在處理這個時可以使用預處理語句,但我仍然想知道SQL注入是如何在這裏執行的。在這種情況下可以執行SQL注入嗎?

$name = mysql_real_escape_string(htmlspecialchars($_POST["Name"])); 
$age = (int) mysql_real_escape_string(htmlspecialchars($_POST["Age"])); 
$amount = (int) mysql_real_escape_string($_POST["Amount"]); 

$sql = "insert into nice_table set 
        name='{$name}', 
        age='{$age}', 
        amount='{$amount}'"; 


$db->sql_query($sql); 

執行SQL注入的時候,我不知道很多關於各種不同的方法,但我已經看到了東西,通過這個就好了,沒有任何數據庫錯誤。使用它而不是經典的準備語句實際上是否安全?

例如,什麼會通過?我一定錯過了一些東西,因爲它不能這麼簡單,而且仍然像預先準備的陳述一樣緊張,對吧?

+0

'htmlspecialchars'作出的重要補充是不是爲了防止SQL注入。你應該做的是學習使用帶有綁定變量的預處理語句。那麼你不會想知道「我做對了嗎?」 –

+0

這兩個整數的轉換意味着你不需要這些行上的其他任何東西 - 如果已經將它們轉換爲整數,那麼通過這些路由無法進行SQL注入。至於'$ name','htmlspecialchars'也不是必需的。如果您正在使用它來保護XSS,則在呈現名稱時使用此功能是正常的,而不是在存儲時使用此功能。 – halfer

回答

3

mysql_real_escape_string ALONE無法阻止所有類型的SQL注入。

只要你需要逃避,你需要它,儘管「安全」的,而是因爲它是通過SQL語法要求。而在你不需要它的地方,逃跑對你來說無法幫助你。

這個函數的用法很簡單:當你在查詢中使用帶引號的字符串,你必須逃脫它的內容。不是因爲某些虛構的「惡意用戶」,而僅僅是爲了逃避這些用來劃定字符串的引號。這是非常簡單的規則,但是PHP人員卻極其錯誤。

這只是語法相關的功能,而不是安全相關的。

根據這個功能在安全問題,認爲這將「保護您免受惡意的用戶數據庫」將帶領您注射。

的結論,你可以讓自己: 沒有,這個功能是不夠的。

準備好的聲明也不是銀彈。它僅覆蓋了一半可能的情況。見我的famous question for the details

+0

如果'mysql_real_escape_string'不足以防止注入,你能澄清你的答案來解釋還需要什麼嗎? – halfer

+0

準備語句的使用可以避免SQL注入在很多情況下。如果你想避免所有類型的SQL注入,請參考http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php/8255054#8255054 – Sriraman

+0

因此,在說「mysql_real_escape_string ALONE無法阻止所有類型的SQL注入「,您所要做的一點是開發人員需要檢查動態構建的SQL以確保不會創建意外查詢。這是真的,但我不希望OP從你的答案中理解非參數化解決方案是脆弱的 - 如果它們寫得很好,它們仍然是安全的。 – halfer

2

mysql_函數已棄用。 Preffer mysqlipdo類。

而且AFAIK,可以使用特殊字符避免mysql_real_escape_string

我願意使用prepared statements驗證。你可能只需要albusumericsdot就可以輸入名字。這將有助於太:P

+1

我認爲在名字中帶撇號的人應該被允許使用':)'。 – halfer

+0

是的。我甚至沒有想過,因爲在我的國家人們的名字沒有撇號:P – jgabriel

1

不,你是()正確使用mysql_real_escape_string,所以這將是安全的。

對於後兩個變量,你也可以做

$age = intval($_POST["Age"]); 
$amount = intval($_POST["Amount"]); 

,這將是一樣安全。 Intval總是返回一個整數(錯誤時爲0),所以不可能包含任何非mysql安全字符。

相關問題