發現mysql_real_escape_string() 在不同php版本中表現不同。網上看安全開發文檔的時候,文檔中說,正確使用mysql_real_escape_string()前需要指定mysql串連字元集即使用mysql_set_charset()函數,如果不指定字元集且使用的字元編碼是類似GBK的寬字元,可能導致寬字元注入。
這裡我做了一個小實驗,只使用了mysql_real_escape_string(),未使用mysql_set_charset()函數指定當前串連字元集,在php版本為5.2.17時,可以寬字元注入成功;在php版本為5.3.29時,寬字元注入不成功,查看mysql日誌,顯示寬字元處也被轉義了。
代碼:
$conn = mysql_connect('localhost', 'root', 'root') or die('bad!');mysql_query("SET NAMES 'GBK'");mysql_select_db('test', $conn) OR emMsg("串連資料庫失敗,未找到您填寫的資料庫");if(get_magic_quotes_gpc()){ $id = isset($_GET['id']) ? mysql_real_escape_string(stripslashes($_GET['id'])) : 1;}else{ $id = isset($_GET['id']) ? mysql_real_escape_string($_GET['id']) : 1;}//執行sql語句$sql = "SELECT * FROM news WHERE tid='{$id}'";$result = mysql_query($sql, $conn) or die(mysql_error());?>
使用php版本為5.2.17時mysql日誌:
2 Query SET NAMES 'GBK' 2 Init DB test 2 Query SELECT * FROM news WHERE tid='-1ࠜ' union select null,concat(name,0x40,pass),null from admin#' 2 Quit
使用php版本為5.3.29時mysql日誌:
1 Query SET NAMES 'GBK' 1 Init DB test 1 Query SELECT * FROM news WHERE tid='-1\ࠜ' union select null,concat(name,0x40,pass),null from admin#' 1 Quit
這裡我的問題是,php版本為5.3.29時不需要使用mysql_set_charset()指定串連字元集了嗎?如果不需要它是怎麼判斷的!!!!
回複內容:
發現mysql_real_escape_string() 在不同php版本中表現不同。網上看安全開發文檔的時候,文檔中說,正確使用mysql_real_escape_string()前需要指定mysql串連字元集即使用mysql_set_charset()函數,如果不指定字元集且使用的字元編碼是類似GBK的寬字元,可能導致寬字元注入。
這裡我做了一個小實驗,只使用了mysql_real_escape_string(),未使用mysql_set_charset()函數指定當前串連字元集,在php版本為5.2.17時,可以寬字元注入成功;在php版本為5.3.29時,寬字元注入不成功,查看mysql日誌,顯示寬字元處也被轉義了。
代碼:
$conn = mysql_connect('localhost', 'root', 'root') or die('bad!');mysql_query("SET NAMES 'GBK'");mysql_select_db('test', $conn) OR emMsg("串連資料庫失敗,未找到您填寫的資料庫");if(get_magic_quotes_gpc()){ $id = isset($_GET['id']) ? mysql_real_escape_string(stripslashes($_GET['id'])) : 1;}else{ $id = isset($_GET['id']) ? mysql_real_escape_string($_GET['id']) : 1;}//執行sql語句$sql = "SELECT * FROM news WHERE tid='{$id}'";$result = mysql_query($sql, $conn) or die(mysql_error());?>
使用php版本為5.2.17時mysql日誌:
2 Query SET NAMES 'GBK' 2 Init DB test 2 Query SELECT * FROM news WHERE tid='-1ࠜ' union select null,concat(name,0x40,pass),null from admin#' 2 Quit
使用php版本為5.3.29時mysql日誌:
1 Query SET NAMES 'GBK' 1 Init DB test 1 Query SELECT * FROM news WHERE tid='-1\ࠜ' union select null,concat(name,0x40,pass),null from admin#' 1 Quit
這裡我的問題是,php版本為5.3.29時不需要使用mysql_set_charset()指定串連字元集了嗎?如果不需要它是怎麼判斷的!!!!
這個和 PHP 版本沒有關係,mysql 和 mysqli 擴充是直接使用 C 語言開發的,而且 mysql 的第三方庫也是通過 C API 提供的。
所以,這個應該和 mysql.dll 的版本有關,也就是 mysql lib 的版本。
mysql 擴充的版本可以使用 mysql_get_client_info()
函數獲得。
至於你的問題,可以參考一下 MySQL 的開發人員手冊:23.8.7.53 mysql_real_escape_string()