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.

  • Check all required variables are present.
  • Check that values have been assigned.
  • Check the data type is as expected. Functions include:

:* 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).

  • Check the value is within acceptable ranges. For example:

:* A select box should only return one of the listed values. :* Names should only include alphanumeric characters.

  • Reject data that does not conform to expectations.

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.

Cross-site scripting

(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'); 
echo $html;

URLs containing variables that could potentially have been manipulated by users need to be escaped twice:

$URL[ 'value' ] = urlencode( $value ); // escapes the value variable
$link = "{$url[ 'value' ]}";
$html[ 'link' = htmlentities( $link, ENT_QUOTES, 'UTF-8' ); // escapes the html

Session fixation

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:

  • Disable remote file access (allow_url_fopen).
  • Use the open_basedir option in PHP to restrict filesystem access.
  • Check filenames with realpath() and basename().

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:

  • realpath() returns the full path to a file, resolving any special characters like directory traversals.
  • Basename() just returns the file name from the path.
  • Combine them to verify the file name by resolving the full path to the file then extracting the file name and comparing it with the user-supplied one:
$filename = $_POST[ 'filename' ];
$verified_file_name = basename( realpath ($filename ) );
If $suspect_file_name !== cleaned_file_name
// error

File uploads

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.

File access

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.

  • php_value session.save_path /myown/path

If you have .htaccess rights and Apache is configured to let you over-ride options you may be able to make this change yourself.

PHP code

Disable dangerous function calls like system() and eval() by setting disable_functions in php.ini.

  • disable_functions system, eval


Disable the following in php.ini:

  • register_globals
  • magic_quotes_gpc
  • allow_url_fopen
Last modified on 2010/11/28 by Anonymous
The comments are owned by the poster. We aren't responsible for their content.