为什么mysql_real_escape_string()不能正常工作?

时间:2011-05-01 06:17:17

标签: php character-encoding mysql-real-escape-string

mysql_real_escape_string()的文档中说:

  

......,考虑到目前的情况   这样连接的字符集   把它放在一个安全的地方是安全的   的mysql_query()

现在为什么它在this example中无法正常工作?

$c = mysql_connect("localhost", "user", "pass");
mysql_select_db("database", $c);
// change our character set
mysql_query("SET CHARACTER SET 'gbk'", $c);
// create demo table
mysql_query("CREATE TABLE users (
    username VARCHAR(32) PRIMARY KEY,
    password VARCHAR(32)
) CHARACTER SET 'GBK'", $c);
mysql_query("INSERT INTO users VALUES('foo','bar'), ('baz','test')", $c);
// now the exploit code
$_POST['username'] = chr(0xbf) . chr(0x27) . ' OR username = username /*'; 
$_POST['password'] = 'anything'; 
// Proper escaping, we should be safe, right?
$user = mysql_real_escape_string($_POST['username'], $c);
$passwd = mysql_real_escape_string($_POST['password'], $c);
$sql = "SELECT * FROM  users WHERE  username = '{$user}' AND password = '{$passwd}'";
$res = mysql_query($sql, $c);
echo mysql_num_rows($res); // will print 2, indicating that we were able to fetch all records

我们在调用mysql_query("SET CHARACTER SET 'gbk'", $c)之前更改了字符集mysql_real_escape_string,那么为什么这个函数不知道新的字符集?

2 个答案:

答案 0 :(得分:0)

您正在阅读错误的文档。

您在谈论mysql_real_escape_string,但您指的是mysqli_real_escape_string的文档。请注意其他 i

mysqli_real_escape_string的文档说:

  

mysqli :: real_escape_string -   mysqli_real_escape_string - Escapes   字符串中的特殊字符供使用   在SQL语句中,考虑到   考虑当前的charset   连接

然而,mysql_real_escape_string的文档(在示例中使用):

  

mysql_real_escape_string - Escapes   字符串中的特殊字符供使用   在SQL语句中

答案 1 :(得分:0)

SET CHARACTER SET / SET NAMES 不够来防范GBK攻击,具体取决于您使用的MySQL版本。

如果可以,请使用mysql_set_charset / mysqli_set_charset或准备好的陈述。

您还希望使用MySQl 5.0.77或更高版本。 See this earlier post of mine for more information。如果您使用的是旧版本的MySQL,那么可以在没有_set_charset功能的情况下容易受到攻击。

使用预准备语句完全绕过了这个问题。