Is Your PHP Code Secure?
There are quite a few malicious users out there. If you haven’t considered your backend security, your website could be in a world of trouble from attacks. This is a beginners guide to what the bare minimums are when it comes to security.
Trust No One
The biggest issue in terms of security is trusting your users. If you have a form and you automatically assume that the user is going to put their name in the name field, you’re less likely to write code that will validate what users are typing in. From a security perspective you have to think of your users as the shifty looking guy on the corner. Don’t trust them. Consider all input data tainted like the moldy piece of cheese in the back of your fridge. In PHP, a general rule of thumb is that all data in PHP’s superglobals ($_POST, $_GET..etc) should be considered tainted. Even the $_SERVER array is not fully safe because it contains some data provided by the client. The only exception to this rule is the $_SESSION array, which is kept on the server and never over the internet.
Are You Filtering?

Filtering is simply the process of making sure that only good input data is processed. There are two common ways of handing this, Black listing and White listing.
Black Listing
Black listing is the less restrictive form of the two. It assumes that the programmer knows everything that isn’t allowed to pass through. An example of this might be to check for profanity. The programmer would create a list of swear words, and for every input the code would cross reference this list to see if it matches the list. If it does, then the program handles it accordingly.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?php //List of bad words. $blacklist = array("bad","word","bleck"); //Good input, no words are in blacklist. $goodInput = "This is good input"; //Has words in blacklist. $badInput = "This input is bad ... bleck"; function inputClean ($input, $blacklist){ foreach ($blacklist as $word) { $pattern = '/'.$word.'/'; preg_match($pattern, $input, $matches, PREG_OFFSET_CAPTURE); if (count($matches) > 0){ echo "You kiss your mother with that mouth?"; return false; }else{ echo "All Clean"; return true; } } } //Outputs "All Clean" inputClean($goodInput, $blacklist); //Outputs "You kiss your mother with that mouth?" inputClean($badInput, $blacklist); ?> |
White Listing
White listing is probably the more common method for security. It automatically assumes that all data is bad. Instead of identifying which information isn’t acceptable, you select which information IS acceptable. Kind of like going through a bag of jelly beans and only eating the red ones….mmmm. Since you control the data that comes in, attackers malicious code won’t be accepted if it doesn’t match the criteria. For this reason white listing is a much stronger protection against attacks then black listing.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php $clean = array(); //Only adds username to clean array if it uses only letters. if (ctype_alpha($_POST['username'])){ $clean['username'] = $_POST['username']; } //only adds password if it uses letters and numbers. if (ctype_alnum($_POST['password'])){ $clean['password'] = $_POST['password']; } //output print_r($clean); ?> |
Do You Escape Your Output?
Output is any information leaving your application. This can mean text going to a web browser, or to your database. Escaping the output ensures that there are no harmful commands within the output. So for example, in a blog you might have a comments section where users can input any info the might like. What if that info is JavaScript? When you output the comments and they’re not escaped, the JavaScript will display too. This can mean stealing of your users cookies, passwords, etc. Escaping is super important for protecting the recipient of your output, whether it is your database or your users. Fortunately PHP makes escaping very simple. If you’re escaping content for the web browser you can use the method htmlentities(). This basically turns any special characters into a non harmful version. So the browser will display <script> instead of acting upon it.
Here is an example:
1 2 3 4 5 6 7 8 9 10 11 | <?php $badOutput = "<script type='text/javascript'>alert('Malicious')</script>'"; //Display javascript alert box. echo $badOutput; //Displays "<script type='text/javascript'>alert('Malicious')</script>'" echo htmlentities($badOutput); ?> |
For databases you’ll have to use a different method. For mysql you can use mysql_escape_string(), and if you have it installed mysql_real_escape_string(). The later offers a more extensive job then the first method. Also if you’re using PHP 5 you can use prepared statements. Prepared statements are SQL statements that have place holders. (SELECT * FROM table WHERE `username` = :placeholder) The place holder is then populated afterwards. How can this help you? To use these place holders you have to use the PHP Data Object (PDO). Fortunately PDO does all the hard work of escaping your output for you…isn’t that nice of them.
Here is an example of PDO in action:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?php $clean = array(); //Filter input if (ctype_alpha($_POST['username'])) { $clean['username'] = $_POST['username']; } //Set the placeholder in the sql $sql = 'SELECT * FROM users WHERE username = :username'; //assume we setup the database handler already setup. //prepare the statement $statement = $databaseHandler->prepare($sql); //Give the place holder a value. //PDO object escapes this value $statement->bindParam(':username', $clean['username']); //execute and fetch results. $statement->execute(); $results = $statement->fetchAll(); ?> |
Conclusion
If you took anything away from the post I hope it is to filter inputs and escape outputs. There is quite a few other things that can be done to help with security. What we discussed here should be at least the bear minimum that you use on a regular basis.

