This page has great potential for development and other processes receive the audit of code.
Always initialise variables, particularly if register_globals is enabled.
Ensure input is filtered
All user-supplied data must be inspected to ensure that it is valid before it is accepted for use. This includes all $_GET, $_POST (including hidden fields!), cookie (and session?) variables. Use a 'whitelist' approach: Data is considered invalid unless it can be proven to be valid.
:* Is_string() :* Is_numeric() // will also return true if data is a string containing a number :* Is_float() // remember data passed in by form is typed as string :* Is_array() :* Is_object() :* Ctype functions permit more specific screening of input (see PHP manual).
:* A select box should only return one of the listed values. :* Names should only include alphanumeric characters.
Eliminating SQL injection
An SQL injection vulnerability exists whenever you used un-escaped data in an SQL query. Use msql_real_escape_string() to escape output.
$username = mysql_real_escape_string( $previously_filtered_data[ 'username' ] );
All values within a query should be contained within quotes regardless of data type. Queries that alter the database should be within a $_POST request rather than $_GET.
(maybe should be called 'html injection') A vulnerability exists whenever un-escaped data is output, eg: echo $_POST[ 'user_input' ] // what if user submitted something nasty? Escape the data with htmlentities:
$html[ 'user_input' ] = htmlentities( $_POST[ 'user_input', ENT_QUOTES, 'UTF-8');
URLs containing variables that could potentially have been manipulated by users need to be escaped twice:
$URL[ 'value' ] = urlencode( $value ); // escapes the value variable
May be conducted as a prelude to session hijacking. To prevent, regenerate the session identifier with session_regenerate_id() whenever there is an escalation of privilege (eg. logging in).
Be wary of opening files with user-supplied 'filename data'. Users may pass something nasty instead, like a relative path to a sensitive local file or a URL to open a remote file with exploit code. Don't forget that fopen(), include() and require() all accept URLs as arguments. To prevent problems:
If you have to allow users to specify a file name, use a combination of realpath() and basename() to verify the relative path to the file on your site:
$filename = $_POST[ 'filename' ];
Don't use user-supplied filenames sent by a browser. Create your own temporary file name to handle it. Set a maximum uploadable file size with post_max_size in php.ini to avoid DOS attempts to jam your server. Cookies can be used to overwrite global variables in GET and POST. Check that the uploaded file really *has* been uploaded using is_uploaded_file() Use PHP's move_uploaded_file() which moves a file only if it was uploaded. Use this in preference to copy() or system level functions.
Restrict filesystem acess to a specific directory using the open_basedir in php.ini. Store sensitive data in the database in preference to files [perhaps trust_path is a better option in Impress?]. If you are on a shared server ask the hosting company to store your session files in your own session directory, because otherwise you are probably sharing a session directory with all the other people on the server and everyone's scripts can access everyone else's session files. This involves setting a session path in the VirtualHost block in Apache's httpd.conf.
If you have .htaccess rights and Apache is configured to let you over-ride options you may be able to make this change yourself.
Disable dangerous function calls like system() and eval() by setting disable_functions in php.ini.
Disable the following in php.ini: