Skip to main content

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=1 if the above code snippet is found in auth.php file. The best practice, that every developer should follow, is setting register_globals directive to Off 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

<form action="process.php" method = "post" accept-charset = "utf-8" enctype = "multipart/form-data" name = "frmComment">
 <textarea name = "txtMessage" id = "txtMessage"></textarea>
<input type = "submit" name = "submit" value = "Send" id = "submit" />
</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:

  • Use an extra .php extension on the end of your file. E.g. sensitive.inc.php
  • Secure the .inc file in a .htaccess file:
 
<Files ~".inc$">
   Order allow,deny
   Deny  from all
</Files>

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

Comments

Popular posts from this blog

PHP Code Review Guidelines

General  The code works  The code is easy to understand  Follows coding conventions  Names are simple and if possible short  Names are spelt correctly  Names contain units where applicable  There are no usages of magic numbers  No hard coded constants that could possibly change in the future  All variables are in the smallest scope possible  There is no commented out code  There is no dead code (inaccessible at Runtime)  No code that can be replaced with library functions  Variables are not accidentally used with null values  Variables are immutable where possible  Code is not repeated or duplicated  There is an else block for every if clause even if it is empty  No complex/long boolean expressions  No negatively named boolean variables  No empty blocks of code  Ideal data structures are used  Constructors do not accept null/none values  Catch clause...

PHP script to upload file securely

How to Write a Secure PHP Script for File Uploads File uploads are a common feature in web applications, but they can introduce significant security risks if not handled properly. In this article, we'll walk through the steps to securely upload files to a server using PHP. We'll cover key security measures such as file validation, limiting file types, setting file size limits, and managing file storage. We will also create reusable functions to handle the upload process. 1. Create the HTML Form First, we need an HTML form that allows users to select and upload a file. Ensure that the form uses the POST method and includes the enctype="multipart/form-data" attribute. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Secure File Upload</title> </head> <body> <form action="upload.php" method="post" enctype="multipart/...

Multiple Checkboxes Validation

This is a regular problem and solution is hardly available on google. When we use multiple checkboxes of same group (same name with square brackets) and you've to read the values from server side, then below solution will help you. Here I'm using jQuery (https://jquery.com/) and jQuery Validate plugin (https://jqueryvalidation.org/) For an example, I've to ask a user which of the listed book they are interested to know about <form id="BooksForm" method="post" name="BooksForm"> <p>Books you are interested in </p> <input class="Books" id="Book1" name="Books[]" type="checkbox" value="1" /> The Inner Game of Tennis <br /> <input class="Books" id="Book2" name="Books[]" type="checkbox" value="1" /> Monk who sold his ferrari <br /> <input class="Books" id="Book3" name=...