NameSilo

How To Secure Your PHP Website

Spaceship Spaceship
Watch

Did this help you at all ?

  • This poll is still running and the standings may change.
  • This poll is still running and the standings may change.

selim06

Established Member
Impact
0
I hope everyone reading learns a thing or two. Please participate in the Poll in this Thread, to tell me if this tutorial helped you or not. :)

1 - ALWAYS, and I mean ALWAYS use $_GET and $_POST variables
I've been programming PHP ever since the start of last year. I've learned a lot from then, and the thing that I would like to stress the most is to ALWAYS use $_POST and $_GET variables when you are using some kind of a form, or if you're grabbing information from the trail end of the URL. I hate to admit it, but before I learned about $_POST and $_GET, I used to program very "unsecurely" by not using $_POST and $_GET. In order for $_POST and $_GET to work in a form, you need to set the method= attribute to GET or POST, depending on what you're going to use later on to process the code. You can only use $_GET if you want to collect information from the trail end of a URL. For instance, the URL on the page I'm making this post on, there are two variables that are more than likely using $_GET. "mode" and "p". I can't go on forever explaining how to use $_POST and $_GET, but I do recommend you to read a PHP book or check-out the wonderful documentation available for free at PHP.net. If you use variables without $_POST or $_GET around them (again, when you're collecting information from a form or from the trail end of a URL), you're waiting for disaster to happen. I used to own a gaming site, a very popular one. I soon found out that hackers were using home-made programs in order to "cheat" my web game because I wasn't using $_POST or $_GET. For instance, if you made your own forum without using $_POST or $_GET, hackers can take a few minutes to make a program to flood your forum in a matter of a few seconds. What's even worse is that it's easy enough to do it in PHP. I won't post the code here as I think people might use it to their advantage. Avoid this and your website should be fine. I just remembered, I wrote a tiny code awhile back that prevents most home-made programs from attacking your website. Place this near the top of your layout file and you should be pretty secure. Good luck with it. :)
Code:
if((getenv("HTTP_USER_AGENT") == "Microsoft URL Control - 6.00.8862") || (getenv("HTTP_USER_AGENT") == "Microsoft URL Control - 6.00.8169")){
exit;
}

2 - ALWAYS, and I mean ALWAYS error check EVERYTHING
I recommend you to read my PHP "How To" if you haven't done so already. A few of the things I cover in there are related to error checking. I do recommend you to use error checking codes on MySQL connections/queries, any form processing code (such as if everything that you require was filled in, if a digit box is only digits, etc), and including if you are including files into your scripts. I do recommend you to use user-friendly error codes, because a visitor might run into one and may be a little confused if they see "Error 23". Instead, you could probably use "Error 23 - You forgot to enter your password". The #23 might be used for the programmer to see what could be wrong if they test their code before public use.

3 - Securing your if-then statements
This one is overseen by most people, but I sometimes like to secure my if-then statements even more. For instance, let's say that your site has a "Free Account" level and an "Advanced Account" level. Let's say that you're restricting Free Accounts from accessing the Advanced Account benefits. You set up an if-then statement that is simply put "If the user account is a free account, stop them from accessing this page, display this message, and stop the page load". This could look something like :
Code:
<?php
$level = "Free Account";
if($level == "Free Account"){
exit("Your account is not an Advanced Account, so therefore you cannot access this page.");
}
// Actual content for Advanced Accounts shows up here //
?>
You could secure this even more by doing this instead :
Code:
<?php
$level = "Free Account";
if($level == "Free Account"){
exit("Your account is not an Advanced Account, so therefore you cannot access this page.");
}else{
// Actual content for Advanced Accounts shows up here //
}
?>
Only a few key taps, and you've secured your if-then statement even better. This is good because you know that it's secure and they're not going to access what don't want them to.

4 - Restricting access to hidden folders
This I've seen a few times on some sites. They (like most sites) have images stored away in a separate directory. But, what they don't know is that the directory can be easily accessed where you can see what's inside it by a default Index page from Apache (on an Apache server of course, and no user-made Index file is made, too). If this isn't turned off by default, you can create a file named ".htaccess" (no quotes, and including the . before htaccess) and have this inside it :
Code:
Options -Indexes
This will show a page that denies access to the directory. If (for some reason) you want to see what's in the directory through that default Index file, you would pretty much do the opposite in the .htaccess file :
Code:
Options +Indexes

5 - Securing your secure admin area
One of the things that people forget to do on their website is blocking out the riff-raff from accessing their precious admin areas. Choose difficult passwords (most of mine are all random letters and numbers) that are hard for password cracker programs to choose from a list. I have seen many programs that try to hack through FTP accounts. They have huge dictionaries of passwords that worked on other sites that get hacked. By me looking in a few of them, they don't bother to try random passwords like "3qrfdsgsdf44w", as that would take forever to do. This should go for caution for sites with a cPanel control panel, a hacker could easily get the UserName for the cPanel account by looking around the site for any errors with PHP programming. For example :
Code:
Parse error: parse error, unexpected T_IF, expecting ',' or ';' in /home/somesite/public_html/test.php on line 6
As you can see above, "somesite" is the username on the cPanel account. Try to eliminate all test files and errors on your website so that no one can try to hack into your files and databases.

6 - Preventing JavaScript Hijacking
This is one of the most ingenious ways of hacking on websites that I've ever had to encounter. About a year and a half ago, I found out that one of the players on my gaming site was stealing the cookie information that I was using to keep users logged into their accounts. I could not understand how this one user made it possible, but I had researched the situation and found out exactly how he did it and how it worked. Basically, the user put a JavaScript snipplet on his user profile (I had accepted HTML and JavaScript in user profiles on my gaming site), which was grabbing the user's cookie information on the gaming site, the JavaScript code redirected the user to an external website (to a PHP page), and from the PHP page, the data that was collected from the JavaScript cookie code was either eMailed to the hacker or inserted into a MySQL DataBase, I'm not sure which, but it could have been either of them. With the cookie data that he literally stole from someone else's computer (with someone else's username and password in the cookie), he changed HIS cookie information to the one that was eMailed to him, and went to my gaming site. BOOM ! He was in. The only ethical way of stopping this from happening (while accepting HTML and JavaScript) I had blocked out the cookie name that I was using on my site, so that it could not be collected through that JavaScript code. Yes, it may sound very shallow, but it was one of my biggest concerns at one point in time.

7 - Preventing SQL/URL Injection
This will only occur when you do not use $_GET or $_POST variables when you are collecting data from a form or at the end of a page URL. I highly stress using $_GET and $_POST variables, as described in the first tip. SQL injection is where additional data is added at the end of a form field box, and updates other information in the database, perhaps some data that was not supposed to be edited. URL injection is the same and can work different too. Sometimes, you can enter in bits of data at the end of the URL to change some of the programming around, muffing up your programming and allowing hackers to really mess up your database info.

8 - Never Use Sessions !
When I was first developing my popular gaming site a few years ago, I started to use sessions to log users into their accounts, instead of cookies. I found out very quickly that sessions are not what they're meant to be. Apparently, it was swapping user data from one computer to another, and not directing the session data to the correct computer it was meant to go to. For instance, the user "admin" could be swapped with someone else like "blacktopbandit", which can cause a serious problem. I recommend to use cookies HIGHLY over sessions, due to that concern.

9 - Securing Your Cookies
As mentioned in the tip above, I recommend that you use cookies instead of sessions. There can be a variety of concerns with cookies too, but you can secure them by encrypting the data that's inside them. I recommend using the md5() and base64_encode() encrypting methods for cookies (better if both are used). When I did my gaming site, I left the username unencrypted, and let the password be encrypted with the above methods. One thing that most people forget to take into consideration is by checking the cookie data on EVERY page load, to see if it is legit. Check the username, the password (using the encrypting methods as well), and other data that you might have in the cookie as well.

10 - Use Image Verification On Registration Forms
When I had owned my gaming site awhile ago, I found out that bots were crawling my site and registering fake accounts, clogging up the database. To prevent this, I recommend using Image Verification, if your server supports it. In order to use PHP images, you need something called the "GD Library" enabled. If it is not enabled (you can check by running the phpinfo() command on a test page), then ask your web host if they can enable it for you. This eliminated all the bots that were registering fake accounts.

11 - Ask For Help If You Need It !
There are many forums that you can go to, such as :

- SitePoint Forums (http://www.sitepointforums.com/)
- ProgrammingTalk (http://www.programmingtalk.com/)

Basically, post your concerns with your website security, and post some samples of your code if you feel that it is necessary. More than likely, there will be someone that will be more than willing to help you out and get your site in better shape.

12 - Read Security Tutorials
There are many good tutorials on the web that you can check-out if you are unsure that your PHP website is secure. This thread only covers a few topics and concerns, though there may be other things to be considered as well. Surf Google for awhile and I'm sure you'll come up with quite a few.

Hope I've helped.
-Selim
 
0
•••
The views expressed on this page by users and staff are their own, not those of NamePros.
AfternicAfternic
I can add : Always use escape strings functions for your GET/POST variables or other variables

Regards
 
0
•••
I would also add this to the form processing section, even if it isn't an absolute must. When dealing with a sequence of characters or numbers that need to be in a specific order to work properly [ie. website urls, email addresses, etc.], try using regular expressions. They are very useful in error checking because you'll be able to evaluate the string based on the regular expression, and if doesn't match perfectly, it should return an error.

a) When letting other users type and post data on your website, always use the striptags() function so that they can't use HTML or PHP (there's a reason for this - security). PHP can be used for malicious purposes. If you want your users to be able to modify the text's font properties, create some codes similar to BBCodes similar to those on message boards.

b) CHMOD text files with valuable information to 766 or below so that you're the only one who can edit them (you don't want people editting them without you knowing because they can be real malicious about it).

c) Use hidden fields sparingly. They aren't the most secure of features, so only use them if you really to (even if you did need to use them, cookies probably do a much better job as the topic starter explained earlier).
 
0
•••
8) Never use sessions? Heh. Never is a strong word. Use sessions properly, don't store anything of importance in them.

c) Use hidden fields sparingly. They aren't the most secure of features, so only use them if you really to

Correct:
General rule of thumb for me is use hidden fields if they do not need to see the input. Don't use them if they shouldn't be seeing the input.

Don't be lazy when coding.
Sanitize everything. There's alot of good code snippets on this forum for ways to sanitize input and query strings.
 
0
•••
Noobie said:
Don't be lazy when coding.
Sanitize everything. There's alot of good code snippets on this forum for ways to sanitize input and query strings.

As trivial as people might think this is, practising neat coding is actually very important, especially if you're working in a team of web developers. Not only does this reduce the potential of small bugs that are usually the most tedious to find (you know which ones I'm talking about), it also makes it easier for you to modify your code or add more code at a later time.

Another security tip: be very cautious when allowing users to upload files. Try to limit what they can upload, at what size, etc. as much as you can without actually stopping them from uploading altogther. Be wary of possibly dangerous files with mystery extensions, insane file sizes, etc.

Use MAXFILESIZE in the upload input line so as to limit the size to visitors without hacking experience.

Also, include the line "enctype='multipart/form-data'" into any form you create that includes uploading. This makes sure that the upload is successfully uploaded to the temp folder. Not really a security issue, but more of a precaution so that files aren't uploaded and become corrupt.
 
0
•••
selim06 said:
4 - Restricting access to hidden folders
This I've seen a few times on some sites. They (like most sites) have images stored away in a separate directory. But, what they don't know is that the directory can be easily accessed where you can see what's inside it by a default Index page from Apache (on an Apache server of course, and no user-made Index file is made, too). If this isn't turned off by default, you can create a file named ".htaccess" (no quotes, and including the . before htaccess) and have this inside it :
Code:
Options -Indexes
This will show a page that denies access to the directory. If (for some reason) you want to see what's in the directory through that default Index file, you would pretty much do the opposite in the .htaccess file :
Code:
Options +Indexes

An Alternative is to put an index.php/html page in the folder, and of course if it is a php page you could then use it to redirect people to your homepage.

selim06 said:
7 - Preventing SQL/URL Injection
This will only occur when you do not use $_GET or $_POST variables when you are collecting data from a form or at the end of a page URL. I highly stress using $_GET and $_POST variables, as described in the first tip. SQL injection is where additional data is added at the end of a form field box, and updates other information in the database, perhaps some data that was not supposed to be edited. URL injection is the same and can work different too. Sometimes, you can enter in bits of data at the end of the URL to change some of the programming around, muffing up your programming and allowing hackers to really mess up your database info.

Im sorry but that is 100% wrong using $_GET and $_POST will not stop sql injection. Say for example I used
PHP:
'admin or 1=1#'
as my username and because it came from a $_POST variable you assume it to be safe. Your SQL statment now checks a username called admin and doesnt bother checking for a password because 1 does equal 1 and also everything after a # is ignored as it is a comment. Presumably you are used to working with register globals turned on in which case the variable would have slashes added to it which would stop this but should not be relied upon.

selim06 said:
8 - Never Use Sessions !
When I was first developing my popular gaming site a few years ago, I started to use sessions to log users into their accounts, instead of cookies. I found out very quickly that sessions are not what they're meant to be. Apparently, it was swapping user data from one computer to another, and not directing the session data to the correct computer it was meant to go to. For instance, the user "admin" could be swapped with someone else like "blacktopbandit", which can cause a serious problem. I recommend to use cookies HIGHLY over sessions, due to that concern.

There is nothing wrong with sessions but like any user input you must VALIDATE it that includes session id's. When I work with sessions when the person logs in I log information about them. After that every time they traverse my site I check this information and see if it matches there credentials. If it does not I destroy the session and make them login again. Sessions are only dangerous if misused. Also you say you used sessions instead of cookies, cookies can be just as dangerous and to be honest cookies are used alot in sessions (instead of adapting the URL with a session ID). What your server uses depends 100% on your php configuration.

selim06 said:
9 - Securing Your Cookies
As mentioned in the tip above, I recommend that you use cookies instead of sessions. There can be a variety of concerns with cookies too, but you can secure them by encrypting the data that's inside them. I recommend using the md5() and base64_encode() encrypting methods for cookies (better if both are used). When I did my gaming site, I left the username unencrypted, and let the password be encrypted with the above methods. One thing that most people forget to take into consideration is by checking the cookie data on EVERY page load, to see if it is legit. Check the username, the password (using the encrypting methods as well), and other data that you might have in the cookie as well.

Please tell me you do not store your users passwords in the cookies. If you really need to do something like that create a key and store that in the database and send that in the cookie and make it only valid for the lifetime of that session (ie create a new 1 every time they login AND after x amount of time has passed). Also md5() is good but found to have some flaws and can be decrypted quite quickly on a modern pc. If available use sha1()

selim06 said:
11 - Ask For Help If You Need It !

That statement is really the best advice. But 1 thing I would say is to create code then ask people regarding that code and ways it could be improved. Do not as many people do is ask without having any code written. Alot of people think that other programmers are here to do their programming for them.

Man In The Box said:
Use MAXFILESIZE in the upload input line so as to limit the size to visitors without hacking experience.

Of course in addition to doing this ensure that the same check is done server side. The maxfilesize form field can easily be circumvented.

I remember a while back I saw a video on youtube that someone created when doing a security audit on a university site (think it was a university site). All of there validation was done via javascript so all someone had to do was either turn off javascript or create their own form without any in it and you could log in with wrong credentials.

I take it you are an Alice In Chains fan going by your avatar and name Man In The Box. Ooh and welcome to the forum.
 
1
•••
the article is well written and full of content but alot of it is incorrect.

the bit about never using sessions is probably the worst.

EDIT: number 7 is just laughable..sorry
 
Last edited:
0
•••
filth@flexiwebhost said:
Of course in addition to doing this ensure that the same check is done server side. The maxfilesize form field can easily be circumvented.

Exactly. It certainly isn't the best solution, but it's better than nothing. Of course, there are other techniques one can employ when it comes to securing file uploads, but that is the most basic (and easiest to penetrate) technique.

I take it you are an Alice In Chains fan going by your avatar and name Man In The Box. Ooh and welcome to the forum.

Somewhat. But I'm only really fond of their album Facelift, which of course contains Man In The Box. And thank you for the welcome.
 
0
•••
Using sessions is probably one of the most securist ways to do it. Opera, and some other browsers allow you to edit and add cookies. Now.. All you need to do is just go edit a cookie and bam you got admin access.. Now I really don't understand the whole thing here and why you think not to use sessions. I am not trying to destroy your whole write-up but suggest doing some research before you post it. As sessions are ten times more secure than cookies will ever be.

Number 3 is also abit off.. They are not great.. As you can just change your $level variable to lets say "pie" and get in. You need to use elseif commands to make sure you only let in people with the proper value.

PHP:
<?php
$level = "Free Account";
if($level == "Free Account"){
exit("Your account is not an Advanced Account, so therefore you cannot access this page.");
}elseif($level == "Advanced Account"){
// Actual content for Advanced Accounts shows up here //
}else{
// Show error that redirects them to login or something
}
?>

To stop sql interjections.. Using $_GET and $_POST have nothing to do with it. You need to clean away any possible (',&,*,etc) all those special characters need to be cleaned away.

Disallowing javascript to be placed in profiles and signatures is another way. Just do a simple preg_replace or str_replace and replace all <script>,<span>,<div>,etc.. with blank. That would be the best way to get reid of any possible javascript vulnerablities.


Nice job but it needs some editing.

- Steve
 
0
•••
Thanks for all of this suggestions,It will be a good thread to secure our PHP Website's...I may be wrong my PHP level is just intermediate.So please forgive me..Anyway thanks for your respectful replies.
 
0
•••
Appraise.net
Unstoppable Domains
Domain Recover
NameMaxi - Your Domain Has Buyers
  • The sidebar remains visible by scrolling at a speed relative to the pageโ€™s height.
Back