Security
1. Avoid using uninitialized variable.
If the register_globals(php.ini) is turned on , the uninitialized variable can cause security breach.
Example:
Following code is used to recognize admin in 'test.php' script.
<?php
if($user==0) {
$admin = true;
}
?>
If register_globals is on, the url http://www.testdomain.com/test.php?user=0 will declare $user as a global variable with no code required and thus provide admin status.
2. Never trust user data
Example:
<?php
readfile($_POST['filename']);
?>
In this case if you really want the user to be able to specify a filename that gets used in any of PHP's file functions, do something like this:
<?php
$doc_root = $_SERVER['DOCUMENT_ROOT'];
$filename = realpath($filename);
readfile($doc_root.$filename);
?>
You may also want to strip out any path and only take the filename component. An easy way to do that is to use the basename() function. Or perhaps check the extension of the file. You can get the extension using this code:
<?php
$ext = substr($str,strrpos($str,'.'));
?>
3. Make sure users can't pass in arguments that executes other system calls, make sure that the argument itself is ok and only accesses data you want the users to have access to.
Example:
<?php
system("ls $dir");
?>
In this example you want to make sure that the user can't pass in $dir set to something like: ".;cat/etc/passwd". The remedy is to use escapeshellarg() which places the argument inside single quotes and escapes any single quote characters in the string.
<?php
$dir=escapeshellarg($dir);
system("ls $dir");
?>
4. Place included files outside of the DOCUMENT_ROOT directory.
Many users place code in multiple files and include these files:
<?php
require 'functions.inc';
?>
Or perhaps
<?php
require 'functions.php';
?>
Both of these can be problematic if the included file is accessible somewhere under the DOCUMENT_ROOT directory. The best solution is to place these files outside of the DOCUMENT_ROOT directory where they are not accessible directly. You can add this external directory to your include_path configuration setting. Another option is to reject any direct requests for these files in your Apache configuration. You can use a rule like this in your "httpd.conf" file:
<Files ~ "\.inc$">
Order allow,deny
Deny from all
</Files>