ggggus said:
I just wanted to protect from injection
It depends on what you mean by 'injection' i.e. SQL Injection, Code Injection, XXS or all of the above...
SQL injection for MySQL can be taken care of pretty easily with mysql_real_escape_string(), type casting, and quotes.
mysql_real_escape_string() will handle all the quote issues with a value. (I have yet to see an exploit of a quote not being escaped)
Type casting can be used on integers. mysql_real_escape_string() will not escape ';'s which can be a problem with variables that are used as integers in a statement (hence the use of 'string' in the function name).
For example:
Code:
//normal post value
$_POST['column_id'] = '15';
//hacking attempt
$_POST['column_id'] = '15; DELETE FROM [i]table_name[/i]';
//sql where $_POST['column_id'] is used...
$sql = 'SELECT *
FROM [i]table_name[/i]
WHERE [i]column_id[/i] = '.mysql_real_escape_string($_POST['column_id']);
As you can see the value for $_POST['column_id'] is still a security threat when using mysql_real_escape_string().
To prevent such an attack I prefer to use type casting. It is faster than using the ctype functions and a lot faster than using regular expressions. So my code validation for an integer will look something like:
Code:
if ((int)$_POST['column_id'] != $_POST['column_id']) {
trigger_error('not a valid integer');
}
//or if you want to try to clean it (not a good idea)
$_POST['column_id'] = (int)$_POST['column_id'];
Finally, MySQL (and some other dbs), will allow you to put quotes around all values including integers. So another way to mitigate the threat above would be:
Code:
$sql = 'SELECT *
FROM [i]table_name[/i]
WHERE [i]column_id[/i] = "'.mysql_real_escape_string($_POST['id_column']).'"';
Just to be safe I usually use all three on integers, but this could be over kill.
Some general rules I live by when dealing with security...
Filter all external data; this means anything that does not originate in your script, whether it is coming from $_SERVER, a database, or user input, consider it tainted until it has been filtered.
Do not try to clean data; if it fails your validation routine, then reject it and display a friendly error message.
Always use a 'white list' approach when possible i.e.
Code:
switch ($_POST[‘subject’]) {
case ‘pre-purchase questions’:
case ‘customer support’:
case ‘other’:
$subject = $_POST[‘subject’];
break;
default:
trigger_error();
}
And as
Chris Shiflett always says: 'filter input, escape output'