Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is mysql_real_escape_string() broken?

Some people believe that mysql_real_escape_string() has some flaws and cannot protect your query even when properly used.
Bringing some fossilized articles as a proof.

So, the question is: is mysql[i]_real escape_string() totally unacceptable?
Or is it's still possible to use this function to create your own kind of prepared statements?

With proofcode, please.

like image 425
Your Common Sense Avatar asked Mar 13 '11 11:03

Your Common Sense


People also ask

Is mysql_real_escape_string deprecated?

This extension was deprecated in PHP 5.5. 0, and it was removed in PHP 7.0.

Is mysql_real_escape_string secure?

PHP provides mysql_real_escape_string() to escape special characters in a string before sending a query to MySQL. This function was adopted by many to escape single quotes in strings and by the same occasion prevent SQL injection attacks. However, it can create serious security flaws when it is not used correctly.

What is the use of mysql_real_escape_string () function?

The real_escape_string() / mysqli_real_escape_string() function escapes special characters in a string for use in an SQL query, taking into account the current character set of the connection.

Why is the use of mysqli_real_escape_string () so important?

The aim of the function mysqli_real_escape_string is to try to ensure that the data that is sent to the mysql server is safe - it attempts to remove characters that are often used in sql injection.


2 Answers

From the MySQL’s C API function mysql_real_escape_string description:

If you need to change the character set of the connection, you should use the mysql_set_character_set() function rather than executing a SET NAMES (or SET CHARACTER SET) statement. mysql_set_character_set() works like SET NAMES but also affects the character set used by mysql_real_escape_string(), which SET NAMES does not.

So don’t use SET NAMES/SET CHARACTER SET but PHP’s mysql_set_charset to change the encoding as that is the counterpart to MySQL’s mysql_set_character_set (see source code of /ext/mysql/php_mysql.c).

like image 169
Gumbo Avatar answered Oct 07 '22 11:10

Gumbo


However, even with legacy code and old server versions, the vulnerability can only be triggered if the character set of the database connection is changed from a single-byte one like Latin-1 to a multibyte one that allows the value 0x5c (ASCII single quote) in the second or later byte of a multibyte character.

Specifically, UTF-8 does not allow that, unlike older Asian encodings like GBK and SJIS. So if your application does not change the connection character set, or changes it only to UTF-8 or single-byte ones like Latin-n, you're safe from this exploit.

But best practice is still to run the newest server version, use the correct interface to change character sets, and use prepared queries so you don't forget to escape stuff.

like image 42
LHMathies Avatar answered Oct 07 '22 13:10

LHMathies