[PHP] addslashes和mysql_real_escape_string的區別


1. 兩者皆為預防資料庫被攻擊的函數。
2. 不要使用mysql_escape_string,它已被棄用,請使用mysql_real_escape_string代替它。
3. 儘管使用了addslashes,我還是可以在不知道用戶名和密碼的情況下成功登錄。我可以輕鬆的利用這個漏洞進行SQL注入。要以免這種漏洞,使用mysql_real_escape_string、準備語句(Prepared Statements,即「參數化查詢」)或者任意一款主流的資料庫抽象類庫。

// 轉義用戶名和密碼,以便在SQL 中使用
$user = mysql_real_escape_string($user);
$pwd = mysql_real_escape_string($pwd);

使用 quote 避免 SQL Injection;相當於 mysql_real_escape_string()
如果連線方式用的是PDO,mysql_real_escape_string() 要改用 quote()

$db = mysql_connect("localhost", "username", "password");
mysql_select_db("database", $db);
 
$string = mysql_real_escape_string($string, $db);
$query = "SELECT * FROM my_table WHERE item_cat='".$string."' ORDER BY item_date DESC LIMIT 5";
$result = mysql_query($query);
 
if ( mysql_num_rows($result) > 0 ) {
    while ( $row = mysql_fetch_assoc($result) ) {
        echo $row['item_title'] . '<br />';
    }
}

$db = new pdo("mysql:host=localhost;dbname=database_name", "username", "password");

$string = $db->quote($string);
$query = "SELECT * FROM my_table WHERE item_cat=$string ORDER BY item_date DESC LIMIT 5";
$result = $db->query($query);
 
if ($result != false) {
    while ( $row = $result->fetch(PDO::FETCH_ASSOC) ) {
        echo $row['item_title'] . '<br />';
    }
}
 
$result  = null;

- 不使用addslashes的理由一:

addslashes不知道任何有關MySQL連接的字符集。如果你給所使用的MySQL連接傳遞一個包含位元組編碼之外的其他編碼的字元串,它會很愉快地把所有值為字元『、「、\和\x00的位元組進行轉義。

如果你正在使用不同於8位和UTF-8的其它字元,這些位元組的值不一定全部都是表示字元『、「、\和\x00。可能造成的結果是,MySQL接收這些字元後出現錯誤。

如果要修正這個bug,可嘗試使用iconv函數,將變數轉為UTF-16,然後再使用addslashes進行轉義。

- 不使用addslashes的理由二:

與addslashes對比,mysql_real_escape_string同時還對\r、\n和\x1a進行轉義。看來,這些字元必須正確地告訴MySQL,否則會得到錯誤的查詢結果。

- addslashes V.S. mysql_real_escape_string

在GBK里,0xbf27不是一個合法的多字元字元,但0xbf5c卻是。在單位元組環境里,0xbf27被視為0xbf後面跟著0×27(『),同時0xbf5c被視為0xbf後面跟著0x5c(\)。

一個用反斜杠轉義的單引號,是無法有效阻止針對MySQL的SQL注入攻擊的。如果你使用addslashes,那麼,我(攻擊者,下同)是很幸運的。我只要注入一些類似0xbf27,然後addslashes將它修改為0xbf5c27,一個合法的多位元組字元後面接著一個單引號。換句話說,我可以無視你的轉義,成功地注入一個單引號。這是因為0xbf5c被當作單位元組字元,而非雙位元組。

Source

PHP mysql_real_escape_string() 函数
PHP函數addslashes和mysql_real_escape_string的區別
Getting Your Feet Wet with PDO and Migrating Old MySQL Code
[PHP] PDO 的使用方法

沒有留言:

技術提供:Blogger.