Well, if anyone would like to volunteer to be a sql injector for
fpsrc.cz.cc/ to test the forms out, please try to inject. Don't delete anything, please xD
Thanks
As Chris stated, using PDO is a good alternative and what I prefer to do myself. But if that's not your cup of tea, then just read over your code and make sure you're following basic security principles.
The first is to assume only one thing about incoming user data (whether it's from a form, the URL encoding, etc.): it's malicious. The only assumption you should ever make about your users in general is that they're only interested in bringing your application to its knees. No piece of user input should be trusted (and you never place untrusted input into your SQL queries) until you've proven it can be.
The easiest thing to do is to escape quote characters inside user input. This is done automatically by PHP if Magic Quotes are enabled (it is by default). For portability sake you should use an alternative method to take care of this though. In PHP, when working with MySQL, you have
mysql_real_escape_string. How you might take care of this:
$params = $_POST;
if (get_magic_quotes_gpc ())
{
$params = array_map ("stripslashes", $params);
}
$params = array_map ("mysql_real_escape_string", $params);
If Magic Quotes are enabled and you pass the data through
mysql_real_escape_string you'll alter the original state of the input. So you need to strip the slashes and then pass it through the escape string method, which is called no matter what.
You'll also need to keep in mind that there are special characters other than quotes and their terminators. These special characters (namely % and _) should be escaped in any SQL query. You could use a
str_replace but a more
efficient alternative is the
addcslashes method.
$sql = addcslashes (mysql_real_escape_string ($userInput), "%_");
Or, keeping with the prior example of using array mapping to apply certain methods to every piece of input coming in:
$params = $_POST;
if (get_magic_quotes_gpc ())
{
$params = array_map ("stripslashes", $params);
}
$params = array_map ("addcslashes", array_map ("mysql_real_escape_string", $params), array ("%_"));
Escaping quotes and special characters isn't enough though. Keeping with the zero-assumptions policy you need to be restrictive about data types. Take the following query for example:
$sql = "SELECT * FROM table WHERE id > {$num}";
In this case
$num should never be anything but an integer. As such why should you accept anything that isn't numeric? This is something you see happen all the time: developers don't even bother to check if the variable that represents their integer ID field is actually an integer. A simple check solves the problem of people trying to pass through faulty strings in this case:
if (is_numeric ($num))
{
$sql = "SELECT * FROM table WHERE id > {$num}";
}
Now while common practice says not to place quotes around integer values in a query, you
will want to place them around sting types such as VARCHAR or BLOB.
if (is_numeric ($num))
{
$sql = "SELECT * FROM table WHERE id > {$num} AND name = '{$someName}'";
}
Long story short: so long as you never assume anything about your user input and don't use it until you've fully vetted it, your applications should be sound against SQL injection vulnerabilities.