Security has always been a concern of web developers. No site is safe from hacking attempts. Developers need to take precautions when building their applications so that they don’t become the victim of a hacking attempt. There are a number of things PHP programmers can do to prevent these kinds of attacks.

What Is XSS?

XSS stands for Cross Server Scripting, and is the most common technique for hacking into a website. Most of the tips we will be talking about today will be things designed to prevent XSS attacks on your server. XSS is when someone injects code into your website, and gets it to execute. This can be used for a variety of malicious purposes.

Here is an example of a simple XSS attack I was able to perform on my site. I noticed that my user name was contained inside a tag on my profile page. I changed my user name to this:

This caused an alert fired away every time someone opened my profile page. It would not have been difficult for me to import an external JavaScript file, or write one that did something more malicious.

List of common XSS exploits

Sanitizing Input

Most XSS attacks come from manipulating the input of a site. Input comes in two forms: Forms and GET variables. You need to take care to properly sanitize these inputs before doing anything else with them. Here are a few things you can do to make sure the input you receive is safe:

Use PHP’s addslashes Function

This is a very simple thing you can do that can help prevent attacks. Simply run all of your input through the addslashes method in PHP. The slashes help escape characters that could otherwise be dangerous.

Use the strip_tags Function

strip_tags() is another handy PHP function that can help sanitize input. You also have the option of allowing certain tags, so if you have a page where users should be allowed to use some HTML (for example, a blog post) you can still allow them to use some tags. However, be wary of allowing particularly dangerous tags, such as <script> or <iframe>.

Remove JavaScript From Input

By Using regular expressions, we can make sure that no JavaScript gets through to execute. While using strip tags to remove tags can take care of some JavaScript, it doesn’t handle instances where people may put a JavaScript event on another tag, such as an <a> tag. Below is a simple function that removes JavaScript from the input it is given, by using regular expressions:


function removeJavaScript($input){
  return  preg_replace('#]*>.*?#is','',$input);
}

Remove Flash From Input

Much like JavaScript, Flash can also be embedded via XSS and used for malicious purposes. Below is another function, which will strip Flash from the input given:


function removeFlash($input){
    return preg_replace("/<object[0-9 a-z_?*=":-/.#,\n\r\t]+/smi", "", $input);
}

Putting It All Together

Below is a handy function I’ve written that can handle all of the above methods of cleaning input. It also gives you the option of allowing JavaScript, Flash, or certain HTML tags:


function sanitizeInput($input,$allowedTags=””,$allowJavaScript=false,$allowFlash=false){
	$input  =  strip_tags($input,$allowedTags);
	if(!$allowJavaScript){
		$input = preg_replace('#]*>.*?#is','',$input);
	}

	if(!$allowFlash){
		$input = preg_replace("/<object[0-9 a-z_?*=":-/.#,\n\r\t]+/smi",
"", $input);
	}
	return $input;

}

Check The Referring Page

Web sites are able to send requests from any server to another, and this can be dangerous. One way of making sure input is coming from where it is supposed to is to use the $_SERVER array in PHP and check what the referring site is. You can also add unique keys to forms and some pages to make sure that the input you are receiving is coming from a reliable source.

NETTuts has a great tutorial on this: Secure Your Forms with Form Keys

Using Encryption

One of the biggest no-nos in all of web programming is storing sensitive information in plain text inside of a database. Things like passwords, social security numbers, and credit card numbers are very common pieces of data that should not be stored in a database.

It is doing a disservice to the users of your site, because if your database was ever to be compromised, you have put your users in addition to yourself, at risk.

PHP’s md5 and crypt functions are great tools for making sure your database is secure. Crypt allows you to use a salt variable, to help make encryption more secure, while md5 does not. Here is an example of how to encrypt passwords, and how to verify them when a user tries to log on, using the crypt function:


//encrypt the input
$input  = $_POST['password'];
$salt    =  “makeThisSecure”;
$safePassword  = crypt($input,salt);
//just re encrypt the password to check
$password_attempt = “password”;
if(crypt($password_attempt,$salt) == $safePassword){
	//log the user in
}

Using CAPTCHAs

If you have any kind of form that does not require a user to be logged in, using CAPTCHAs is a good way to prevent spam bots from inputing bogus information. There are a lot of good CAPTCHA scripts that are freely available, such as : www.phpcaptcha.org/, and here is a tutorial on how to create your own CAPTCHA

Have Secure Passwords

A number of hacking attempts come from people not having very strong passwords. Even Twitter fell victim to this not long ago (link to article). Make sure that your password has a good mix of letters, numbers, and symbols, and that it isn’t a word that can be found in the dictionary. This includes passwords that are common words, but are spelled in ‘leet speak’, for example drag0n.

If you take these steps, you should have a much more secure web application. It can sometimes be a hassle to update existing projects, but it is nothing compared to the headache you will suffer if you don’t, and become the victim of an attack. It is important that you don’t think of securing an application as an afterthought, but instead something that is part of your regular development process.

  • http://ottergoose.net Ottergoose

    1. Using the same salt for all of your hashes makes your data less secure.

    2. You cannot rely upon checking the referring page. That value is set by the browser, and can therefore be set to anything the user (or attacker) desires. Furthermore, some security solutions actually strip the referring information, which could make your website unusable.

    3. The sanitizeInput function provided is woefully inadequate. There is no instance where you should trust your users to insert their own JavaScript, Flash, or any other HTML into your website. Period. There are way too many ways they could do something nasty.

    4. The statement “input comes in two forms: Forms and GET variables,” doesn’t make any sense. Forms can send data via post or get (that’s what the “method” in your form tag is for). Additionally, users might be able to get information onto your site via input from your database, their cookies, RSS feeds, etc.

    5. Strip_tags alone shouldn’t be used with the idea that it’s preventing XSS. At a minimum, run any user provided data through the htmlentities function.

    6. Addslashes won’t prevent SQL injection attacks. Look into “prepared statements” and the PDO library for some assistance there.

    7. Read through the comments on the PHP documentation pages and look at some of the legit web security blogs like http://shiflett.org/ and http://jeremiahgrossman.blogspot.com/

    8. Never trust what you read about security on a design blog. Ever.

  • http://www.daslaboratorium.de Philipp

    strip_tags() is no where near being save. There are numerous ways to encode chars like “” and therefor: If someone is really serious in hacking your site (he will certainly be aware, that strip_tags() is used), he will find ways to encode the entered string in a way, that he will get his hacks through strip_tags().

  • Pingback: geeee's status on Wednesday, 01-Jul-09 23:59:18 UTC - Identi.ca

  • http://chacha102.com Chacha

    Just by the way, in the 2nd to last paragraph I think you meant to link to the article where the Twitter account got compromised.

  • Pingback: PHP Security: Guidelines to Lock Down Your Website | Choose Daily

  • Josh Rice

    While you point out all the right things to check for, your solutions are terrible. As the first commenter pointed out checking referrers is pointless. They can very easily be spoofed, and some security/privacy software block them from even being sent!

    addslashes() is bad news. As your image suggests, use mysql_escape_string()

    crypt() is a extremely insecure and barely qualifies as encryption in my book. Look into mcrypt() or database level encryption instead.

  • http://www.ots.ac.cr paviles

    Muchas gracias por compartir este artículo. Muy concreto y completo!!

  • http://www.crearecommunications.co.uk Mike

    Thanks for the tips, security is definitely a major concern when it comes to web development,

  • http://reboltutorial.com reboltutorial

    Wow very nice pcitures, I’m impressed :)

  • Pingback: 10 Great Design, Development And Inspirational Posts From Around The Web | Spyre Studios

  • http://www.surfionline.com/ Chris Boulton

    There’s two types of sanitization – sanitization for input (saving) and sanitization for output.

    addslashes() should NEVER be used to sanitize data for output unless you’re in a Javascript string or similar where you need it slashed.

    htmlspecialchars/html_entities is what you want to do for any data that is being output to HTML, assuming you don’t want anything passed through.

    mysql_real_escape_string() (or equivalent for other DB engine you’re using) is what should be used to escape input being supplied around in database queries. Of course, what’s even better are parameterized queries/prepared statements.

    The “disable flash” is also awfully inadequate. Not to mention it’s easily bypassed if I do ….

    Checking referring pages should also NEVER be relied upon from a security standpoint. Ever. It’s easily forged, can be disabled etc etc. The form keys however, are the correct approach.

  • Pingback: Eiencafe.com --> New way to graphic

  • Pingback: ??????? 02 (29.06 - 05.07.2009) | ?????? ?? ?????? ????????

  • http://www.danhbaweb20.com Danh ba web 2.0

    Thanks for great tips, keep up !

  • http://www.jsxtech.com Jaspal Singh

    Excellent tutorial for PHP Freaks.
    Thanks for sharing.

  • http://themikecam.com Miquel

    I can only echo the misgivings of previous commenters and request that you please remove or amend this article. Whilst the intent behind it is laudable, it proposes unsafe solutions and it is irresponsible of you to continue to present them as such.

  • http://www.utahwebdesign.ws/ Sherwin

    Thanks a lot for the great tips. Security is indeed a very important factor to consider for our websites, especially now that there so many hostilities circling in the web.

  • http://www.lionlilly.com/ website development chennai

    Its an fantastic PHP tool to secure.And the explanation is superb.I am impressed about this post.wonderful and useful for us.Thanks and keep sharing.

  • http://www.lionlilly.com/ web development chennai

    Its simply superbtool tips.Nice keep share with me.

  • http://www.bing.com/ Cami

    What a neat article. I had no inkinlg.