0

在mysql_real_escape_string()的文档中它说:

...,考虑到连接的当前字符集,以便将其放在 mysql_query() 中是安全的

现在为什么它在这个例子中不能正常工作?

$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,那么为什么这个函数不知道新的字符集呢?

4

2 回答 2

0

您正在阅读错误的文档。

您在谈论mysql_real_escape_string,但您指的是mysqli_real_escape_string的文档。注意额外的i

mysqli_real_escape_string 的文档说:

mysqli::real_escape_string -- mysqli_real_escape_string -- 转义字符串中的特殊字符以用于 SQL 语句,同时考虑连接的当前字符集

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

mysql_real_escape_string — 转义字符串中的特殊字符以用于 SQL 语句

于 2011-05-01T06:44:48.760 回答
0

SET CHARACTER SET/不足以防止 GBK 攻击,具体取决于您使用的 MySQL 版本SET NAMES

如果可以,请使用mysql_set_charset/mysqli_set_charset或真正准备好的语句。

您还需要使用 MySQl 5.0.77 或更高版本。 有关更多信息,请参阅我的这篇较早的帖子。如果您使用的是旧版本的 MySQL,如果没有这些功能,您可能会受到攻击。_set_charset

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

于 2011-05-01T06:55:58.243 回答