2014-02-28 35 views
1

首先 - 我知道準備好的語句是「銀彈」,我「應該使用它們」 - 但是對於這個項目來說,這是不可行的。相信我,當我說它不能發生。所以,在講道開始之前...;)SQL注入,real_escape_string和帶引號的查詢

因此,我一直在閱讀SQL注入今晚4個小時。

,每反駁使用real_escape_string(我與PHP的工作和MySQL)說,基本上,real_escape_string不會停止這樣的:

SELECT * FROM something WHERE id=1 or 1=1; 

權。得到它了。

但自從我大約15年前第一次接觸到mysql時,我寫過的每個查詢都總是單引號引用查詢中發送的所有參數。就像,如果我沒有單引號參數,我有這種感覺,查詢將失敗。所以我總是單引號。所有。的。時間。

和:

$_POST['userinput'] is submitted as "1 or 1=1"; 
$clean = $db->real_escape_string($_POST['userinput']); 
$db->query("SELECT * FROM something WHERE id='$clean'"); 

如何有史以來被打破?它可以?我從來沒有見過一個射擊不使用無引號版本的real_escape_string的例子。

它在引號中。所有可能從報價中跳出的內部報價都會逃脫。

再說一遍:我知道準備好的陳述是最好的。那不是我要問的。我在問,我上面寫的是否可以打破?

我看不到方法。

回答

2

我相信你的代碼是安全的。由於您已將字符串用引號括起來,因此or被解釋爲SQL關鍵字的唯一方法是讓輸入包含結尾引號。但real_escape_string將逃避,所以它不會結束字符串。

什麼你也可以這樣做對於那些要求是整數值是

$clean = (int)$_POST['userinput']; 

這將1 or 1=1轉換輸入1

+0

+1。 OP代碼是「安全的」。 'real_escape_function'在輸入字符串中標識「危險」字符,並返回一個「安全」字符串以包含在SQL語句中,如果這樣做也是以「安全」方式完成的,如OP示例中那樣,將它用SQL文本中的單引號括起來。 – spencer7593

0

對你的整數使用intval()

+2

或者,如果您正處於微觀優化的心情,則可以通過使用'(int)'轉換爲int來避免函數調用。 –

+0

簡單的權利,但如果你在微觀優化的心情,你將不會使用PHP ;-) –

+0

我總是通過整數插入或選擇單引號以及沒有問題。它一直工作。引用它是否存在性能問題? IE:爲什麼把它當作一個整數並且不加引號? – InfernusDoleo

0

在某些情況下,可能會破壞Mysql_real_escape_string。看到這裏:https://stackoverflow.com/a/12118602/2167896

除了複雜的漏洞,如果你沒有使用準備好的語句,所需要的只是項目上的任何程序員的一個錯誤,而且你已經陷入困境。在商業環境中,這嚴重限制了您可以加入項目的程序員數量,並且絕對有必要對每個查詢進行質量控制。

如果您計劃擴大規模,請認真考慮重新編寫您的所有查詢;您甚至可以在使用最新技術和mysql增強功能的同時提高性能,因此這不是完全損失。

+0

我已閱讀準備好的語句,實際上減慢了查詢速度,除非您一遍又一遍地運行相同的查詢。這是一個數據庫沉重的Web應用程序頁面加載,做許多各種SQL查詢(不重複任何),然後退出。一旦頁面加載結束,顯然不能保留已準備好的語句。那麼性能改進在哪裏? – InfernusDoleo

+0

哦,我之前閱讀過這篇文章 - 那基本上只有當你使用舊版本的MySQL和/或使用一些非標準的字符集。我永遠不會將我的字符集設置爲GBK,而我的MySQL是現代的,所以它不是問題。 – InfernusDoleo

+0

不是這樣,一個不會從參數查詢中看到性能提高的應用程序極不可能。以下是一些文章: http://www.mysqlperformanceblog.com/2006/08/02/mysql-prepared-statements/ https://www.simple-talk.com/sql/t-sql-programming/參數化查詢的性能影響/ http://codebetter.com/davidhayden/2006/01/05/parameterized-queries-and-performance/ –

0

事實上,準備好的聲明不是一個特徵,而是一個原則。而且可以自行實施。你必須做的,而不是找藉口。

你的格式化字符串文字的想法是正確的。這種格式必須通過預先準備好的語句完成。

您正在使用的手動格式化是分離和可拆卸的。你在一個地方添加引號並將它們轉移到另一個地方 - 這僅僅是許多災難的來源。即使你將它移動到一個地方 - 你的格式仍然是可拆卸的,這意味着它可以從實際的查詢執行中移開並在那裏被遺忘。

這就是爲什麼您應該始終使用佔位符來表示查詢中的變量,然後在替換數據時格式化數據。

這就是爲什麼準備的聲明是一顆銀彈,並不是因爲某人剛剛告訴過你。

+0

感謝您的演講,我說我不想聽到。 – InfernusDoleo