In Tips Jul 1, 200916
PHP Security: Guidelines to Lock Down Your Website
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.
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.














16 Comments
Jul 1, 2009
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.
Jul 1, 2009
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().
Jul 1, 2009
[...] http://designreviver.com/tips/php-security-guidelines-to-lock-down-your-website/ [...]
Jul 1, 2009
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.
Jul 2, 2009
[...] Choose It AKPC_IDS += "32,"; This entry was posted on Thursday, July 2nd, 2009. You can leave a comment, or trackback from your own site. [...]
Jul 2, 2009
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.
Jul 2, 2009
Muchas gracias por compartir este artículo. Muy concreto y completo!!
Jul 2, 2009
Thanks for the tips, security is definitely a major concern when it comes to web development,
Jul 3, 2009
Wow very nice pcitures, I’m impressed
Jul 4, 2009
[...] PHP Security: Guidelines to Lock Down Your Website: No website is safe from hackers so why not make sure yours is as secure as possible? This article from Design Reviver offers some priceless tips and techniques. [...]
Jul 4, 2009
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.
Jul 5, 2009
Weekly Fave’s…
Another Sunday, another week favorites .
Week from June 28 to July 4, 2009:
Tutorials
Photoshop Grunge City Magic and special light effects need Apophysis, too Construct a Novel Victorian Theatre Setting How To Create An Abstract Body Portrait …..
Jul 6, 2009
[...] PHP Security: Guidelines to Lock Down Your Website [...]
Jul 8, 2009
Thanks for great tips, keep up !
Nov 8, 2009
Excellent tutorial for PHP Freaks.
Thanks for sharing.
Dec 16, 2009
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.
Leave a Comment