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

SET CHARACTER SET/SET NAMESは、使用している MySQL のバージョンによっては、GBK エクスプロイトから保護するには不十分です。

可能であれば、mysql_set_charset/mysqli_set_charsetまたは実際の準備済みステートメントを使用してください。

また、MySQl 5.0.77 以降を使用する必要があります。 詳細については、私のこの以前の投稿を参照してください。古いバージョンの MySQL を使用している場合、関数がないと脆弱になる可能性があります_set_charset

準備済みステートメントを使用すると、この問題を完全に回避できます。

于 2011-05-01T06:55:58.243 に答える
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 に答える