2013-08-21 74 views
0

我陷入了一個SQL注入問題。我的頁面顯示如下表的數據:SQL注入|更改ID值

<input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>" /><?php echo $row['data']; ?><br /> 

我怎麼能肯定的是,提交的值是該特定行的id的不是一個隨機數「注射」的頁面?

很顯然,我將開始檢查該ID返回is_numeric() /通過mysql_real_escape_string().

得到它。然後,我想到了兩個選項:

  • 添加一個隱藏的輸入與副本的$ row ['data'],這樣我就可以在 之前檢查id和數據之間的對應關係mysql_query()

  • 將行的ID從一個自動遞增的數字改爲一個大的隨機數,這樣我就可以降低幸運命中的機率。

我有錯嗎?有什麼更好的想法 感謝您的幫助!

+0

我首先閱讀[如何防止SQL注入PHP?](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)和[爲什麼我不應該在PHP中使用mysql_ *函數?](http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php) – 2013-08-21 00:32:50

+0

感謝您的提示! – Greg

回答

2

你不能。你的兩個選項也有根本的缺陷:

  • 一個可以改變複選框的值可以很好地改變隱藏的輸入值。
  • 您的「隨機ID」仍然可以在Dev Tools,Firebug或類似工具上看到。

而是擔心用戶如何發送的數據,你應該擔心數據是否有效,以及是否用戶對給定操作的權限的。


而且,is_numeric不是我喜歡的,因爲它會返回true爲十六進制和指數描述。我建議你用ctype_digit檢查或乾脆做一個(int)投,例如:

​​3210

非數字字符串轉換爲0和自動遞增字段通常具有1作爲第一個值。如果0是一個有效的值,您需要調整上面的代碼,例如:

if (!isset($_POST['id']) || !ctype_digit($_POST['id'])) die('invalid data'); 
$id = (int) $_POST['id']; 

之後,請檢查您是否DB存在給定的ID。做適當的權限檢查,就是這樣。


不要緊,你的服務器是如何得到的數據,重要的是數據是有效的,並具有執行給定的操作權限的用戶。您在前端/界面中執行的任何操作都可以輕鬆地由黑客或任何經驗豐富的Web開發人員進行更改和操作。

專注於重新分割非授權訪問並保持數據庫完整性。無論是從您的頁面,從被篡改的頁面還是通過終端發出請求,所有標題和發佈的數據都可以輕鬆地複製到,看起來像從您的頁面發出的請求。


畢竟,我不確定是否可以調用這個「SQL注入」。您的應用程序的功能需要一些包含整數值的輸入。現在剩下的是檢查是否提供了必要的輸入並且是有效的。所有的用戶輸入必須被視爲不安全,並在被扔進查詢之前進行適當的驗證和轉義。

另外,看看PDO哪個處理價值逃逸很好。 mysql_*擴展名和mysql_real_escape_string函數已被棄用,並且非常容易出現人爲錯誤。

至於預防SQL注入,linked thread在問題的評論是一個很好的閱讀。

+0

非常感謝這個詳盡的解釋! 我幾乎沒有發現mysql API被棄用......我明白,現在,使用mysql還不是一個安全問題,而是在將來溝渠,對吧? – Greg

+0

@Greg實際上使用'mysql_ *'已被棄用了十多年,但是是的。它不是'mysql_ *'是*邪惡*,但它是人們如何使用它。誤用它非常容易。你可以使用PDO連接到一個MySQL服務器,並且通過微軟PDO教程只需要一兩個小時的時間就可以瞭解答案,並且可以更快地學習它,這樣可以在將來避免很多麻煩。 '=]' –

+0

一般的建議是,如果您正在開始一個新應用程序或剛開始學習,最好從最新的擴展開始,而不是那些舊的已棄用的東西。 ':)' –