Reputation: 47947
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 :)
Upvotes: 8
Views: 2186
Reputation: 100175
Just for info:
mysql_real_escape_string()
does not escape %
and _
. These are wildcards in MySQL if combined with LIKE, GRANT, or REVOKE
.
Upvotes: 1
Reputation: 157828
There is only one thing about mysql_real_escape_string() and SQL Injection -
The former does not have a slightest relation to the latter.
Although it sounds paradoxical, nothing can be more true.
Here are 2 statements proving it
Thus, when applicable, this function have to be used anyway, despite of whatever dangers or fears. And in any other case it will help nothing.
The only thing I have to add is that prepared statements do not provide full protection either. Here is the explanation and recommendations: https://stackoverflow.com/a/8255054/285587
Upvotes: 0
Reputation: 6751
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.
Upvotes: 9
Reputation: 437326
There are two things that can go wrong with mysql_real_escape_string
:
SET NAMES
instead of mysql_set_charset
as is proper, it can still leave you vulnerableUpdate:
SET NAMES
!)Upvotes: 3
Reputation: 14060
mysql_real_escape_string()
can fail to clean the input.
Since mysql_real_esacpe_string()
takes character set into account while cleaning strings.
There's the problem. You can change character via mysql_query
function sending the query to change connection's character set. However, mysql_real_escape_string()
is oblivious to the set you're using and it will escape some characters improperly.
The other thing is constantly invoking it manually. Even wrapping it in a function is a P.I.T.A. because it implies you have to create some sort of database wrapper / database abstraction layer of your own in order to be able to automate calls to mysql_real_escape_string()
.
That's why we have PDO in PHP which helps us alleviate all of the above and you get to use parametrized prepared statements which are preferable way of dealing with repeating queries that alter the data.
Prepare the statement, bind input variables and it will clean the input according to the database driver being used and connection's character set. It's less code and completely safe.
Upvotes: 0