なぜmysql_real_escape_string()が正しく機能しないのですか?
-
27-10-2019 - |
質問
のドキュメントで 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
, 、では、なぜこの機能が新しい文字セットを知らなかったのですか?
解決
SET CHARACTER SET
/ SET NAMES
は 十分でない 使用しているMySQLのバージョンに応じて、GBKエクスプロイトから保護するため。
可能であれば、使用してください mysql_set_charset
/ mysqli_set_charset
または実際の準備されたステートメント。
また、MySQL 5.0.77以上を使用する必要があります。 詳細については、私の以前の投稿をご覧ください. 。あなたがmysqlの古いバージョンを使用しているなら、あなたは できる なしで脆弱になります _set_charset
機能。
準備されたステートメントを使用して、この問題を完全にバイパスします。
他のヒント
間違ったドキュメントを読んでいます。
あなたは話している mysql_real_escape_string 、しかし、あなたはの文書に言及しています mysqli_real_escape_string. 。追加に注意してください 私.
mysqli_real_escape_stringのドキュメントは次のように述べています
mysqli :: real_escape_string -mysqli_real_escape_string - 接続の現在のcharsetを考慮して、SQLステートメントで使用するために文字列で特殊文字を逃がします
一方、mysql_real_escape_stringのドキュメント(例で使用されています):
mysql_real_escape_string - sqlステートメントで使用するために文字列で特殊文字を逃がす