Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why mysql_real_escape_string() shouldn't avoid any SQL Injection?

I've heard people say (in relation to C#/SQL Server, but also in relation to PHP/MySql): Don't escape strings manually - use stored procedures instead.

Ok, I can accept this suggestion, but why? Many say (including on SO) mysql_real_escape_string() is quite enough, mysql_real_escape_string() is good, mysql_real_escape_string() is the first way of protection.

Why? Is there a case where mysql_real_escape_string() can fail? At least one... I don't need many :)

like image 815
markzzz Avatar asked Dec 19 '11 11:12

markzzz


People also ask

Does mysql_real_escape_string prevent SQL injection?

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.

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.

Is mysql_real_escape_string deprecated?

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

How can SQL injection be prevented?

The only sure way to prevent SQL Injection attacks is input validation and parametrized queries including prepared statements. The application code should never use the input directly. The developer must sanitize all input, not only web form inputs such as login forms.


3 Answers

When mysql_real_escape_string FAIL:

$sql = "SELECT * FROM users WHERE id=" + mysql_real_escape_string($_GET['id']);

If $_GET['user_id'] is set to 1 OR 1=1, there are no special chars and it's not filtered.

The result: All rows are returned.

It gets worse. How about this... what if $_GET['user_id'] is set to 1 OR is_admin = 1?

The function is only designed to be used when inside single quotes.

like image 112
Moz Morris Avatar answered Sep 20 '22 18:09

Moz Morris


There are two things that can go wrong with mysql_real_escape_string:

  • You can forget to use it
  • If you are using some specific multibyte connection encodings, and you have set these encodings with SET NAMES instead of mysql_set_charset as is proper, it can still leave you vulnerable

Update:

  • You are safe with UTF-8 (although this does not mean that you should continue using SET NAMES!)
  • For an explanation, see here
like image 30
Jon Avatar answered Sep 20 '22 18:09

Jon


Just for info: mysql_real_escape_string() does not escape % and _. These are wildcards in MySQL if combined with LIKE, GRANT, or REVOKE.

like image 43
Sudhir Bastakoti Avatar answered Sep 19 '22 18:09

Sudhir Bastakoti