2009-10-13 73 views
5

從歷史上看,我一直使用PHP MySQLi準備好的綁定參數查詢是否安全?

mysql_real_escape_string() 

從用戶得到的所有輸入的是結束了觸摸數據庫。

既然我已經完全轉換爲MySQLi,並且我正在使用綁定參數準備的查詢,我是否已經有效地消除了SQL注入攻擊的可能性?

我是在說我不再需要

mysql_real_escape_string()? 

糾正這是我的理解和我的一個項目的基礎: http://sourceforge.net/projects/mysqldoneright/files/Base/MysqlDoneRight-0.23.tar.gz/download

這不是我想錯了,雖然作爲現在我已經發布了它,它也可能會影響其他人。

所有用戶提供的輸入現在都會在bind_parms中結束。
準備階段提供的查詢是靜態的。

回答

6

這不是那麼簡單。你可以用它代替插值應用程序變量爲SQL表達式來取代文字值僅的綁定參數:

$sql = "SELECT * FROM MyTable WHERE id = ".$_GET["id"]; // not safe 

$sql = "SELECT * FROM MyTable WHERE id = ?"; // safe 

但是,如果你需要進行動態查詢的一部分,除了字面價值?

$sql = "SELECT * FROM MyTable ORDER BY ".$_GET["sortcolumn"]; // not safe 

$sql = "SELECT * FROM MyTable ORDER BY ?"; // doesn't work! 

該參數將始終被解釋爲一個值,而不是列標識符。您可以使用ORDER BY 'score'運行查詢,該查詢與ORDER BY score不同,並且使用參數將被解釋爲前者 - 恆定字符串'score',而不是名爲score的列中的值。

因此,在很多情況下,您必須使用動態SQL並在查詢中插入應用程序變量以獲得所需的結果。在這些情況下,查詢參數不能幫助您。您仍然需要保持警惕並進行防禦性編碼,以防止SQL注入漏洞。

沒有框架或數據訪問庫可以爲你做這項工作。您始終可以構建包含SQL注入缺陷的SQL查詢字符串,並且在數據訪問庫看到SQL查詢之前執行此操作。那麼它應該如何知道什麼是故意的和什麼是缺陷?

這裏有方法來實現安全的SQL查詢:

  • 濾波器輸入。跟蹤插入到SQL查詢中的任何變量數據。使用輸入filters去除非法字符。例如,如果你期望一個整數,確保輸入被限制爲一個整數。

  • 退出輸出。在此上下文中的輸出可以是您發送到數據庫服務器的SQL查詢。你知道你可以爲值使用SQL查詢參數,但是列名是什麼?你需要一個標識符的轉義/引用函數,就像舊的mysql_real_escape_string()用於字符串值。

  • 代碼評論。讓別人成爲第二雙眼睛並瀏覽你的SQL代碼,以幫助你找到你忽略使用上述兩種技術的地方。

+0

是的。注意到你不能執行ORDER BY?位參數。好答案。 – 2009-10-13 22:17:06

+0

我得到了一個downvote? Downvoter,你應該描述你爲什麼認爲這個答案不令人滿意。也許我可以改進它。 – 2015-02-16 07:20:31

13

是的。使用準備好的查詢將會跳過參數。

+0

簡短,甜美,準確。 – ceejayoz 2009-10-13 17:04:46

+0

謝謝。只是想確保我沒有失去明顯的東西。我傾向於這樣做。 – 2009-10-13 17:14:06

1

將參數綁定到預處理語句時,會自動轉義數據,因此在發送之前不應將其轉義。雙逃脫通常是一件壞事。至少,它會產生醜陋的結果,並在稍後出現額外的逃脫字符。

相關問題