Monday 4 April 2011

4 Most Important PHP Security Measures

We can say that PHP is a mature language with lot’s of useful, but potentially dangerous features. The rapid growth of the language and the dynamic nature of the Web let people easily create dynamic web pages without any prior knowledge in computer science or the architecture of the Internet.

In this tutorial we’ll have a look at 4 important PHP security measures that you should implement in order to develop a safer website.

1. Register Globals

Up until PHP version 4.2.0 the register_globals directive’s default value was On. One of the most controversial change in following versions was that the PHP core developers changed this default value to Off, not because the directive itself was insecure, but the common misuse of it was.

Note: This feature will be removed starting with PHP 6.0.0

When this directive is On, PHP will inject extra variables in the script such as HTML request variables, etc. The problem with this approach is that a developer cannot rely anything outside of his script and by injecting these variables an outside attacker could overwrite already defined variables or create potentially dangerous ones. For example:

PHP could inject these sort of variables in a script
$username = 'hacked_username';

Now if a $username variable was already set this would overwrite it.

Another good example can be found on php.net

if ($authorized) {
//show members only page
}

An attacker could alter the value of this variable simply by using GET auth.php?authorized=1if the above code snippet is found in auth.php file

The best practice, that every developer should follow, is setting register_globals directive toOff and use the already defined PHP superglobals such as $_GET, $_POST.

register_globals directive is found in the php.ini file.

2. Error Reporting

When developing a complex website or web application enabling errors display is essential. A developer cannot fix the committed errors if he can’t see them, but once the website is in production the errors display should be disabled, because PHP errors provides detailed information to the outside attacker.

A good approach is to enable error display in development environment:

error_reporting(E_ALL);
ini_set('display_errors','On');

And once in production environment disable error display, but enable error logging to a file:

error_reporting(E_ALL);
ini_set('display_errors','Off');
ini_set('log_errors', 'On');
ini_set('error_log', '/path/to/error/log');

Alternatively you can use error_reporting(E_ALL | E_STRICT), this is the highest setting, offering suggestion for forward compatibility too.

3. Cross-Site Scripting (XSS)

Cross-site scripting vulnerability is the most common form of attack on websites. The mistake made by developers is not filtering input data from web forms and not escaping the output.

For example we have the following comment form:





The application displays the following data like:
echo $_POST['txtMessage'];

The vulnerability is that the application doesn’t filter the input and escape the output. Let’s say someone writes the following javascript in the comment textarea:
alert ('hacked');

If an application doesn’t escape this output on every page request a Javascript alert box will pop up. The best a developer can do is to filter out any HTML tags from the data with:
$clean_message = strip_tags($_POST['txtComment']);

And escape it when outputting the date with htmlentities:
htmlentities($clean_message, ENT_QUOTES, 'UTF-8');

A better solution is to use HTML Purifier to filter out any unwanted malicious input and to test your web forms that it’s XSS proof use the XSS cheat sheet.

4. Exposing Sensitive Information

Many web developers store sensitive information in files such as database passwords and other credentials. If these files are not properly secured an attacker could see the contents of them, therefore hacking the applications database, etc.

The most common file extension for php include files is .inc. By using this extension and not properly creating parsing rules in Apache, a developer could create a major security hole in the web application.

In Apache configuration the default file type for unknown file extensions is text/plain. If the.inc file is not set to be parsed as a PHP file and it is in the document root then we can access this file and see the contents of it by visiting the corresponding URL.

The best solution to this problem is to store these files outside of your document root (e.g. /www, /public_html, etc.). A best practice is to place the most essential files in your document root.

If you don’t have access outside your document root then at least use the following 2 methods:

1. Use an extra .php extension on the end of your file. E.g. sensitive.inc.php
2. Secure the .inc file in a .htaccess file:



Order allow,deny

Deny from all



Summary

* Set register_globals directive to Off
* Disable error display in production environment
* Avoid XSS attacks, filter your input and escape your output
* Move all your sensitive information outside of your document root, if that’s not possible add an extra .php extension to your .inc files and/or secure them in a .htaccess file



‎"Trying to get everyone to like you is a sign of mediocrity." -- Colin Powell