Thanks to
DemonicPuffin for this post.
Nobody can tell you exactly what security holes will exist in your code...as it depends on your exact situation.That being said...a few general guidelines:
Do NOT Use Register Globals!!!!!
eg:
always use: $_GET,$_POST,$_COOKIE,etc.
so if you have a url like file.php?id=1
use:
PHP Code:
$id = $_GET["id"];
echo $id;
NOT
PHP Code:
//only works if register globals is set to ON in php.ini
echo $id;
The reason for this becomes apparent when doing similar using a form with the POST method....depending on register globals will allow a user to set variables via the query string....as if it were a post form..or worse...a cookie!
Always Use addslashes(); on data being inserted into a db(If magic_quotes_gpc is off)
PHP Code:
$string = "I am a 'string with quotes in it'";
@mysql_query("INSERT INTO table (column) VALUES ('".addslashes($string)."')");
will add preceeding backslashes to the quotes.
This is one very simple way to help prevent a very simple method of attack known as an SQL injection...which is purposely adding SQL queries to the input of a script.This vunerability is extremely common...and can cripple/completely destroy a site in seconds...if the right attacker comes along.
Using addslashes requires stripslashes on output...
PHP Code:
$query = @mysql_query("SELECT col FROM table LIMIT 1");
$row = mysql_fetch_array($query);
echo stripslashes($row["col"]);
using the example string from before..this would output:
Code:
I am a 'string with quotes in it '
Whereas without stripslashes...it would output:
Code:
I am a \\'string with quotes in it \\'
Added:
Note that by default,a feature called magic_quotes_gpc(Magic Quotes Get,Post,Cookie) is enabled which will automatically "add slashes" to input from GET,POST and COOKIE variables...a replacement for addslashes may be:
PHP Code:
function EscapeString($text){
if (!get_magic_quotes_gpc()) {
$text = addslashes($text);
}
return $text;
}
Which checks for this feature before escaping the string.
Note that an alternative to addslashes thats quite useful for SQL insertion/queries is:
PHP Code:
mysql_real_escape_string();
So,in keeping with the above....it could be written as:
PHP Code:
function EscapeString($text){
if (!get_magic_quotes_gpc()) {
$text = mysql_real_escape_string($text);
}
return $text;
}
To similar effect.
Sanatize HTML!!!
This is almost as important as "slashing" data.Use of the function
PHP Code:
htmlentities();
will sanatize(eg: disable) any html the user inputs.Why is this important you might ask?very simple...lets say the user posts a reference to a very shady javascript....perhaps one to steal input data from your script...or redirect your users inappropriately.htmlentities will ensure that the script tag...and other html tags...will be nothing more than decorative strings.
So...whats a suggested way to process user input from a protection point of view?
PHP Code:
/*EscapeString Function Originally Posted By Scoutt*/
function EscapeString($text){
/*
ENT_NOQUOTES : does not convert the quotes to its ascii format
If you want it to convert the quotes, use ENT_QUOTES instead
*/
$text = htmlentities($text,ENT_NOQUOTES);
if (!get_magic_quotes_gpc()) {
$text = mysql_real_escape_string($text);
}
return $text;
}
Is an example of a function which should provide adequate processing.
Check,Check,And Re-Check!
If your expecting a variable to be of a certain type...make sure it IS of that type...for example:
PHP Code:
$num = $_GET["num"];
if(is_numeric($num))
{
echo 'Is a number';
}
else
{
echo 'Is NOT a number';
}
now if you save the above code as num.php...and use: num.php?num=1
it will output:
but if you pass it,for example... num.php?num=CHICKEN!!!!!
It will output:
You could also check entry lengths,exact character contents and even type-cast the ones that fail...but this is beyond the scope of this summary.
Also..it's usually good form to check all form values to ensure they've been completed...for example:
PHP Code:
<?
if($_POST["submit"])
{
$txt = trim($_POST["txt"]); //uses trim to remove leading/trailing whitespace
if($txt == '')
{
echo 'You Didnt Enter Your Text';
exit; //ends script execution
}
}
?>
<form action="<?=$_SERVER["PHP_SELF"]?>" method="post">
Name: <input type="text" name="txt"/><br/>
</form>
This would kill the script if the form field is left empty.
Use Error Suppression On A Live Site
PHP errors should be left on for debugging...but never on a live site.You can either suppress errors for functions individually by preceeding them with @...eg:
PHP Code:
@mysql_query("...");
or set them for the whole script by putting
PHP Code:
error_reporting(E_NONE);
as the first line in your script.
It's also worth mensioning that giving your visitors friendly errors may be a good idea..eg:
PHP Code:
@mysql_query("...") or die('An Error Has Occured...please contact the webmaster');
This is by no means exaustive...but I hope it at least helps.
Please feel free to ask questions.
Credits: This post was updated to make references to mysql_escape_string(),htmlentities(); and magic_quotes_gpc.Special Credit goes to Scoutt for suggesting these.