When and How to Sanitize your PHP Variables.

Posted: August 4, 2011 in PHP, PHP, Tutorial, Web Development
Tags: , , , , , , ,

I few weeks ago I wrote a tutorial on how to validate your PHP variables. That is the precursor to this post (You can read it here: http://blackscorner.me/2011/07/28/when-and-how-to-validate-your-php-variables/) in which I explain the basics of validating your PHP variables that you get for use with MySQL (or other SQLs) queries.

In order to get the most out of this tutorial, you will need to be familiar with the following

  • The subjects discussed in the precursor post
  • basic SQL queries
  • using MySQL or other SQLs and PHP together
  • Escape characters (for example how is ‘ different from \’)

Whats The Point?

You may wonder why we need to go through all of this sanitation nonsense in the first place. Well when using SQLs, like MySQL along with user input (Like say storing some information that they gave the website via a form), your site could be vulnerable to what is called a SQL injection. SQL injections, and how they work is a pretty broad topic (one beyond the scope of this post), but they basically consist of a user injecting bad SQL into your query to make it do something you don’t want. Lets take a very basic example:

Lets say that we have a user login system, and the query we use to make sure the login details is correct is:

SELECT * FROM user_table WHERE username=’$username’ AND password=’$password’

Assume that $username and $password are defined earlier in the script. Now if we don’t validate the script, a malicious user can enter something like:

‘ OR 1=1 —

Now, that may seem like a useless string, but now lets look at what our query looks like

SELECT * FROM user_table WHERE username=” OR 1=1 — 

Now the rest after — doesn’t matter because the — operator basically tells SQL to ignore everything after it. It is kind of like commenting out a line of code in PHP. Now what will happen is that 1=1 is always true, so the query will be true, and return a row from your table. The first row specifically in our case with the query above. This would allow a user to access someones account without the proper username and password. If you are unlucky, the admin account (if there is one) may be the first account (since its usually the first account created), and now the malicious user has access to administrative powers. Bad news

So How do we Stop them?

Well, removing all vulnerabilities from your site is almost impossible (as cyber security is an ever changing field) but protecting from SQL injections is pretty straight forward. PHP has a function made just for stopping the kind of attack you see above, but before we start using it on anything and everything we have to be aware of a few things. First, the magic quotes setting for PHP. Nowadays it is usually turned off, and it is recommended that it be turned off. What this setting does is when turned off, it automatically escapes all strings. This is a dangerous action because it is sort of like a 1 size fits all glove for sanitation that has terrible effects depending on the data. You want to sanitize SQL versus HTML vs. bbcode differently. However, if it is on in your system, you can do the following.

if (get_magic_quotes_gpc()==1){
 //its on, lets undo what happened
 //do this for all variables
 $_POST['username'] = stripslashes($_POST['username']);
 $_POST['password'] = stripslashes($_POST['password']);
 //the rest of the post variables you are gonna use.

Now of course it would just be easier to turn this setting off in your php.ini. Consult the manual for details on turning this setting off. The stripslashes() function basically does is remove all the slashes that PHP adds in order to escape the data. PHP adds backslashes before single and double quotes. As you should know, escaping slashes lets you add them to strings that are delimited by them!

 

Now the second thing I need to mention is that we need to consider what type of data we are using. If we are using string data (like usernames, passwords, etc.) then we should escape the string to prevent our basic SQL injection from happening. If it is number data, we should just convert whatever they entered into a number so we don’t have to worry about escaping it. (Entering a string where a number should be in a query will break the script, and may even show an error message that gives the attacker more information about your system. So lets go over each different scenario.

Strings:

For strings, PHP provides a very useful function called mysql_real_escape_string(). It accepts a string as a parameter and and returns the string escaped in such a way to make it safe from basic SQL injections like the one above. So lets give a code example and see what would happen if the attacker tried the simple SQL injection.


//assume we have turned off magic quotes.

$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);

$query = "SELECT * FROM user_table WHERE username='$username' AND password='$password'";
//rest of login stuff below

Now lets see what our injected query would look like

SELECT * FROM user_table WHERE username=’\’ or 1=1 –‘ AND password=”

Here we see that our escape string function made the ‘ that originally broke our query harmless, and this will not let them login as you would expect. Awesome right!

Numbers

Now  if you are expecting the user to enter in a number into the query, we should whatever they enter into a number. So that even if they enter some malicious text, it will be converted to a harmless number. Now assuming we want an integer number, we can easily do something like


$area_code = intval($_POST['area_code']);

//rest of code

Now, if you need a float number, you can use the floatval function instead of intval()!

 

Now What?

Well, we have sanitized some stuff, but not everthing! What if we are getting some information that we will show on our users profile page (like a description or a bio). In fields like these, the user can enter any HTML they want, and could even enter malicious HTML/Javascript or include malicious HTML/Javascript from another site. This is known as Cross Site Scripting (XSS) and is a very real threat to many websites. Now, the most basic way to stop this is to turn all html into html entities. That way, even if they enter HTML, it becomes harmless. HTML entities are special characters that represent HTML characters that you don’t won’t to be interpreted as HTML. For example, the less than sign (<) This can be used to show a mathematical inequality, but in HTML it denotes the beginning of an HTML tag (like <a for example). When you want to show the less than sign without the browser trying to interpret it as HTML, you use HTML entities.

PHP provides a function that converts all HTML special characters into their respective entities called, you guessed it! htmlentities(). Now lets show an example


$bio = htmlentities($_POST['bio']);

Now if the user enters some HTML, it will instead be harmless html entities.

Now, if we want to remove the HTML outright, there is also a function for that. We can use the strip_tags() function which will remove all tags. We can also specify tags to exclude from removal, which would allow you to allow users to enter links, or text formatting tags, but not other tags. For example


$bio = strip_tags($_POST['bio']);//remove all html tags
//or
$Bio = strip_tags($_POST['bio'], "<p><a>");//allow links and paragraph tags

 

And thats it for basic validation! After reading this and the previous article, you should be able to add some basic security to your website! Now there is much more to the website security field than just this, but following these simple steps should allow you to protect your site against most basic attacks. Here are some links to the functions used

 

mysql_real_escape_string(): http://php.net/manual/en/function.mysql-real-escape-string.php

htmlentities(): http://php.net/manual/en/function.htmlentities.php

intval()/floatval(): http://php.net/manual/en/function.intval.php  http://www.php.net/manual/en/function.floatval.php

string_tags(): http://php.net/manual/en/function.strip-tags.php

 

 

 

Comments
  1. […] The second part of this article can be read here: http://blackscorner.me/2011/08/04/when-and-how-to-sanitize-your-php-variables/ […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s