Basic PHP Security

Introduction

Security in PHP has become one of the most popular topics in the PHP community lately, especially with an increased number of exploits and security problems. In this day and age, you must make sure your PHP scripts are airtight, and that they don’t have any security problems.

To make sure the security in your PHP scripts are okay, you have to start with the basics: filter input, and escape output. If you haven’t got that working properly, your scripts will always be open to security problems. Read this article to learn how to properly do these two things.

 

Filter all input

When your script reads any input from an outside source, the input must be treated as dangerous and not to be trusted. The most common variables not to be trusted are: $_POST, $_GET, $_REQUEST but also $_SERVER, which seems unlikely but can also contain dangerous data.

Before you do any further processing with data that comes from a dangerous variable, you first have to validate it and possibly filter it. By validating the data you make sure that it contains only what you want it to contain. For example, if you’re expecting an e-mail address, your validation function would make sure it’s a valid e-mail address, and nothing else.

Let’s have a quick example to show you what I mean. In the code below I first get the e-mail address from the $_POST variable, and then proceed to validate the data:

<?php
$email = $_POST[‘email’]; # At this point it’s still DANGEROUS// Validate e-mail
if (valid_email($email) == false) {
// Not a valid e-mail address
die(‘Invalid E-mail Address!’);
}
?>

The possibility to inject any dangerous data into our script has already been greatly diminished, by checking the data. The valid_email() function is a standard validation function, which can be found in the PHPit Code Snippet Database.

Even though our data is much safer already, we aren’t completely there yet, because we still want to insert the data into a MySQL database, which means we must make sure it’s safe to be inserted. PHP has a standard function called mysql_real_escape_string(), which escapes all the important characters. Another good practice is to always put data between apostrophes in the SQL query (if your database allows it, which MySQL does).

To continue our previous example, it now looks like this:

<?php
$email = $_POST[‘email’]; # At this point it’s still DANGEROUS// Validate e-mail
if (valid_email($email) == false) {
// Not a valid e-mail address
die(‘Invalid E-mail Address!’);
}

// Make sure e-mail is safe for database
$email = mysql_real_escape_string($email);

// All safe now!
?>

Now the data is completely safe, and can be inserted into the database without any worries. To help avoid mistakes it can be a smart thing to give special and dangerous variables a special prefix, for example:

<?php
$d_Email = $_POST[‘email’]; # Dangerous// Do validation

$s_Email = mysql_real_escape_string($d_Email);
?>

This way you will immediately notice when you’re trying to insert a dangerous variable, because it’ll show a d_ variable being inserted. I’ve never used this method myself, but once it you get used to it, it could be a lifesaver!

Escape output

Just like input data, all output data must also be filtered, even when you’re getting “safe” data from a database (which has already been through your input filter). The same variables I just talked about should also be filtered before displaying them.

The most important thing to filter out is HTML tags, as they can cause a lot of damage. The easiest way to do this is with the htmlentities() function which automatically escapes all the HTML, like so:

<?php
echo htmlentities($_GET[‘email’]);
?>

This code immediately removes any possible Cross-Site-Script attacks, whereby an attacker could inject JavaScript into your pages, and steal cookies from other users. If it’s possible, you should also use the third argument of the htmlentities function, which is the encoding/charset type. Even Google isn’t immune to security exploits, as they forgot to use the appropriate encoding when escaping HTML, causing a XSS attack. Read more about this exploit on Chris Shiflett’s blog, but basically you should always set the encoding type:

<?php
echo htmlentities($_GET[‘email’], ENT_QUOTES, ‘UTF-8′);
?>

If you don’t want to escape all HTML tags, but want to allow a few tags you can use the strip_tags() function, but be aware that this could lead to security problems with regards to JavaScript being injected into your pages, even if you disallow the <script> tag. It’s still possible to set events on elements, which are not stripped, e.g. <div onclick=”alert(’Hi!’);”>.

Another possibility is to write your own function (or download one of the hundreds already available on the internet!) that filters only the things that you don’t want. This can often be the best way, but this could also lead to security problems, especially if you forget about something.

Ultimately, the best way to escape output is to use htmlentities() with all three arguments, but this also leaves with limited functionality, like no formatting. One solution to this would be to create your own HTML code, which can be used to format data. Read more about creating your own HTML code in “Create your own BBCode, using PHP”.

Conclusion

In this article I’ve talked about the two basic security principles of PHP programming: filter input, escape output. If you get these two things right, you’re already on the way to a very secure PHP script.

The examples I’ve given are quite simple and cumbersome. I highly suggest you think of a way to (almost) automate the filtering and escaping. A good way would be to write a class which automatically does the necessary tasks, or a few functions that do the job. This is left as an exercise for the reader.

If you want to know more about PHP security, head on over to the following websites for a lot more security advice and examples:

- PHP Security Consortium: excellent security guide, with a lot information. Definite must-read!

- Essential PHP Security: mainly information on the Essential PHP Security book, by Chris Shiflett, but it contains a few free chapters as well.

- Hardened-PHP: not as such a PHP security information website, but it does have security advisories.

website:phpIt.net


You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

AddThis Social Bookmark Button

One Response to “Basic PHP Security”

  1. Monday I was looking for sites about Fixed Rate Mortgages and specifically about database lead loan mortgage and I found your site.

Leave a Reply

Spam protection by WP Captcha-Free