views:

83

answers:

5

Im just wondering, would the following be completely safe or would someone be able to get around it using hexadecimal characters, etc:

$name = mysql_real_escape_string(htmlentities(stripslashes($_REQUEST['name'])));
$query ="SELECT * FROM Games WHERE name LIKE '%{$name}%'";

Thanks.

I know I can use PEAR and other libraries to make prepeared statements. However this question is specifically regaring raw queries.

+7  A: 

mysql_real_escape_string does the trick,.,

[EDIT]

for string use:

$str = mysql_real_escape_string($input);

for numeric values type casting is sufficient like:

$val = (int)$input;
ovais.tariq
-1 mysql_real_escape_string is an a bad choice, if security is the goal, there are some better ways to do this
canni
i dont agree with you., mysql_real_escape_string is a perfect choice for escaping data being inserted into a table and prevents against sql injection,. there are many popular opensource projects using this approach wordpress is one,.
ovais.tariq
one thing more i would like to add is that the biggest advantage of using mysql_real_escape_string lies in the fact that it takes characterset into account when deciding how to properly escape the data
ovais.tariq
I agree, i even think that PDO's internals may use this function/algorithms from it, "not secure" heare is that You manually have to remember about escaping every input value (witch is the most common mistake, simple forget about it), and PDO's way would do this for You, in a abstraction layer
canni
an abstraction layer does help things out i agree but that doesn't mean mysql_real_escape_string is a bad choice :) you could use PDO or any other abstraction layer
ovais.tariq
Charsets are handled quite well with parameterized SQL. One thing people overlook with mysql_real_escape_string(): The string gets expanded on PHP side and *mixed up* with SQL commands. The MySQL tokenizer therefore has to extract and compact the values again. So this is not only slower, but wasting memory twice: in PHP and MySQL.
mario
i haved edited my answer to include ways of escaping data that is not string,.
ovais.tariq
@mario: even if you are using concatenation to create sql commands,. the sql command is sent as a single query to mysql,. i dont quite understand your point about "MySQL tokenizer therefore has to extract and compact the values again". that doesnt make sense., since php is merely sending string to the mysql function as a raw sql which is then sent back to the mysql server.,
ovais.tariq
@mario: one thing i forgot to mention charsets are handled equally well by mysql_real_escape_string() and most of the times PDO is generally an overkill
ovais.tariq
@ovais.tariq for numeric types better way is to use intval($param) / floatval($param) than casting, i've found situations when casting has produced results witch are not expected
canni
yeah u r rite Dariusz Górecki.., but it does depend on situations,. for example if i am always expecting an int value then i might as well use (int) style casting or use the intval function that would be more of a matter of choice,.
ovais.tariq
The important thing to remember is that escaping only works if the variable is quoted (which is one of the reasons parametrized queries are superior).
Tgr
could you explain further what you meant,.
ovais.tariq
+1 for answering the question that was asked, and correctly so.
Ian
ovas it's simple to explain. you can do automated function which will take a lot of parameters and a query like this `SELECT * FROM table WHERE id=%s` and all these %s will be substituted with quoted and escaped strings. But if you try to do the same with `SELECT * FROM table WHERE id=%s LIMIT %s, %s` you will get an error. While parametrized `SELECT * FROM table WHERE id=? LIMIT ?, ?` will run all right. That's the only advantage of prepared statements
Col. Shrapnel
@mario Honestly, in our web applications we barely run a dozen queries. There is not much gain to even mention it.
Col. Shrapnel
@CS: Pointing out that the SQL parser/tokenizer has to reverse the escaping again seems important to me. Ovais didn't seem to know the terminology at all. Of course it's not a serious speed difference, but depending on the input it can lead to memory constraints. If your shared hosting PHP runtime is limited to 8MB and you run on e.g. Drupal, then you'd better not receive a 2MB text file and pipe it through escaping to the database. Come to think of it, this duplicates the string *three* times. Original $_POST[text], addslashed($sql) and once more in mysql_query() sending it over the socket.
mario
@col. sharpnel., i understand your point,. but then how about SELECT * FROM table WHERE id=%s LIMIT %d, %d as in ezSQL,.
ovais.tariq
@mario as far as prepared statements are concerned,. the question is not related to it at all,. the guy is clearly asking about raw queries., you can read the question again,. i think we should strive to provide the answer that the questioner asks not try to show-off our knowledge,.and about prepared statements,.Sometimes prepared statements can actually be slower than regular queries. The reason for this is that there are two round-trips to the server,. so everything has to be seen in perspective,,. before using any solution one should see the needs whether heavy lifting is needed or not,.
ovais.tariq
@ovais I'd like to see an implementation. Do they have their own printf format parser? I see no other way to implement such things. (unless you're doing it '%s' for strings)
Col. Shrapnel
@col shrapnel check out this link http://codex.wordpress.org/Function_Reference/wpdb_Class#Protect_Queries_Against_SQL_Injection_Attacks
ovais.tariq
@ovais: It's likewise totally unrelated to the question if you like the PDO interface or not. It's disingenious to the questioner not to point out the outdatedness of an approach. Don't make up roundtrips, or sometimes slower queries, or a difficult API. Just because there are foremost aging mysql_query() concat tutorials on the web doesn't mean we have to shot low on SO. It's worth to point out an inherently more secure approach. Particularily when the question was about security.
mario
@mario,. i never said i liked it or not., and i am not even talking about PDO, i am talking about prepared statements., PDO is just another abstraction layer like other out there,. and the point i am making is dont use a canon for killing a bee., use the tools according to the requirements.,
ovais.tariq
@ovais: Your misunderstanding is that expression and data intermingling was the native method to interface with SQL databases. Actually parameterized SQL originated with compiled languages, that came und used them long before PHP. The amateurish mysql_query method isn't widespread outside of scripting languages. I'm not sure your canon analogy makes sense therefore. "According to the requirements" does not entail *too much* security precaution? Windows user perchance?
mario
@mario., neither m i against prepared statements nor do i have said that they ought not to be used,. the only thing that i m saying is that use it according to the requirements., and the fact that i am talking here about php is because this question is related to php.,again this forum is not about ridiculing anyone nor is it about showing off your knowledge.,besides php is not just a scripting language,. u have to get your facts straight,.and there are many well followed and well used opensource projects out there (example wordpress) that still use the amateurish mysql_query method
ovais.tariq
+2  A: 

For the SQL just

$name = mysql_real_escape_string($_REQUEST['name']);
$query ="SELECT * FROM Games WHERE name LIKE '%$name%'";

is enough.

More of that, using of htmlentities and stripslashes here is unecessary and buggy.
I doubt you want to search Dankeschön instead of Dankeschön for example.

Note that mysql_real_escape_string obviously works for quoted strings only.

$num = mysql_real_escape_string($_REQUEST['num']);
$query ="SELECT * FROM Games WHERE salary > $num;

would not help

For the other uses there can be other validations.

Col. Shrapnel
+3  A: 

Use parametrized prepared-statements, along with PDO, this will give You the most secure way of sending queries, that PHP can offer, and You'll not have to deal with escaping at all, using that way

canni
Thanks, however not specific to the question of raw queries.
pondpad
A: 

mysql_real_escape_string is enough here and since you tagged it with xss, when reading it from the database and showing it in html use htmlentities to prevent xss.

Leon
I'd strongly suggest htmlspecialchars() instead of htmlentities(). this last one should be banned from usage as totally useless and wrong. Converting letters to entities will never help with security but will mess the source code.
Col. Shrapnel
A: 

Either use parameterized SQL or enforced input filtering:

$query = "SELECT * FROM Games WHERE name LIKE '%{$_REQUEST->sql['name']}%'";

Manual escaping is pretty bad style, because it's too easily forgotten.

mario