Terug naar de voorpaginaTBForum nu ook op je mobiel!
Klik hier voor meer info en gratis link...

Home Nieuw Vraag & Aanbod Forums Artikelen Bedrijvengids Zoeken

   Stefan van Elsas, Particulier
2 nov 2008 08:51 
PHP is a language that is easy to learn. It’s a language that a lot of beginning web developers use to create their first website. They often don’t know about any of the security risks involved in building PHP applications.

This article is meant to help the new (and more experienced) PHP programmers to understand the security risks involved in PHP programming.
If you find this article incomplete, or have something to add to this article, please let me know.

The sections covered in this article are:
- User Input, SQL Injections
- Register Globals
- Includes
- Error reporting
- XSS
- CSRF
- If All Else Fails, Mitigate Damage on Breach

Things to cover in the next article:
- Cross zone scripting
- HTTP header injection / http response splitting
- Eval
- Database users
- Email header injection

Never Trust Your Users

You should ALWAYS verify user input. You can’t trust your users input to be valid. Basically any piece of information coming from the user can be malicious. This includes but is not limited to ALL $_GET, ALL $_POST, ALL $_COOKIE and some $_SERVER vars.

HTML:

<form>
<input type = “text” name = “username” />
<input type = “password” name = “password” />
</form>


PHP:

$rCheck = mysql_query (“SELECT COUNT(*) FROM users WHERE username = ‘” . $_POST[‘username’] . “’ AND password = ‘” . md5 ($_POST[‘password’] ) . “’” );
if ( mysql_result($rCheck,0,0) != 0 ) {
$aRow =mysql_fetch_row(mysql_query(“SELECT * FROM users WHERE username = ‘” . $_POST[‘username’] . “’ AND password = ‘” . md5($_POST[‘password’] ) . “’”);
$_SESSION[‘userID’] = $aRow[‘id’];
$_SESSION[‘rights’] = $aRow[‘rights’];
}


If your PHP code looks like this your application might be vulnerable to serious security risks. If your user would enter their username and password as expected, then everything will work fine. But if it was the users intension to hack into your system, he might enter “admin’ OR 1=1 /*” as his username. The query generated would be:


SELECT COUNT(*) FROM users WHERE username = ‘admin’ OR 1=1 /* AND password = ‘password’


The “/*” part will tell MySQL that the rest is a multiline comment, so this will be ignored. The OR 1=1 clause will always propagate to TRUE, so every row in the database will be selected. As your first user in the database most likely is a user with admin rights, the hacker will be logged in as an admin without ever entering a valid password.

Please be advised that ALL $_GET and all $_POST variables can be tempered with. This includes <select> boxes and checkboxes. You might think that a select box has a limited set of options, but this is a mistake often made. You can always temper with the data.

You should always escape the variables you put into an SQL query, by calling mysql_real_escape_string() or equivalent. If you know the format of a field, you could also check it using regular expressions ( only numbers, telephone, email ) etc.

Register Globals
Unfortunately the PHP setting register_globals is set to ‘On’ by default on servers runnig PHP << 4.2.0. As of PHP 4.2.0 the default is set to ‘Off’, and the functionality is completely removed as of PHP 6.0.0.
Register_globals will inject your script with all sorts of variables, coming from $_GET, $_POST, $_COOKIE and $_SESSION.

Why is this a bad thing?

Take a look at the following code snippet. It might look secure to you, because only if user_login() returns true, the user will be able to see the sensitive data.


if ( user_login() )
$authorized = 1;
If ( $authorized ) {
// show sensitive data

}


If register globals would be on, simply calling the script with ?authorized=1, would give you access to the sensitive data because register_globals will make $_GET[‘authorized’] accessible as $authorized.
The best fix for this is turning register globals off. You could also declare your variables before you start using them, so that you know the initial value of the variable. In our example above, adding $authorized = 0; at the top would do the trick.

Relying on register_globals is bad practice and highly discouraged.

Includes
Including files is a good way to break up sections of your program into separate files. You could for example have a default template, in which you include different files to show in the body of the page.
An easy setup would be something similar to this:


// template stuff
include “includes/” . $_GET[‘page’] ;
//template stuff


The page you request will be inserted into the body of the template, and it’ll show up nicely. But, if the user would enter “../.htpasswd” as a page, it would show up the htpasswd file of your website! You should always validate the file you’re including, before including them.

A simple solution would be using a switch statement, to check if the page is valid:


switch ( $_GET[‘page’] ) {

case ‘validPage.php’: case ‘validPage2.php’:
$sIncludePage = $_GET[‘page’];
break;
default:
$sIncludePage = ‘home.php’;

}
Include “includes/” . $sIncludePage;


Error Reporting
Error reporting is a useful tool when developing a website. It gives you all kind of detailed information on errors that occur. It also feeds a hacker with a lot of useful information to hack your site.
Therefore, it’s good practice to turn error reporting off on live servers, or have them logged into a log file which only you can view.

XSS
XSS ( cross site scripting ) is a bit harder to explain to beginning programmers. If your website is vulnerable, it allows a hacker to execute code he has written himself, and therefore he is able to steel sessions.
It’s best explained by an example. We’ll take a comments system, adding and displaying comments on a blog i.e.


if ( isset ( $_POST[‘add’] ) )
// properly escape strings with mysql_real_escape_string to prevent SQL injections
mysql_query (“INSERT INTO posts SET name = ‘” . mysql_real_escape_string($_POST[‘name’]) . “’, comment = ‘” . mysql_real_escape_string($_POST[‘ comment’] ) . “’”);
// get comments, pseudo code
while ( $comment = fetchComment() ) {

echo $comment[‘name’] . ‘<br />’ . $comment[‘comment’];

}


The example above is vulnerable to XSS. If I would add a comment with <script>alert(document.cookie)</script>, it would popup a box with the cookies from the local user. If you expand the script to mail you the session cookie, you could login as a different user just by hijacking the session.

You can easily prevent this by calling htmlspecialchars() when you output your name and comment.

CSRF
CSRF ( cross site request forgery ) is the opposite of XSS, it uses the trust that a site has for a particular user.
Let’s say I’m logged in into my online banking account, where I can go to the URL mybank.com/transferMoney?to=Name&amount=25 to transfer money to name. This is of course not the case for actual online banks, but for online RPG’s it’s very likely to work like this.

If I would run a website, and display a hidden iframe with the url mybank.com/transferMoney?to=MyName&amount=252525 it would transfer 252525$ to my account.

If we combine this with some sort of XSS attack, I would be able to put the hidden iframe on the profile page in an RPG, and have it transfer an X amount to my account for every user that visits my profile.
Protecting against CSRF in general is fairly simple. You could add a token to the form of a page, which is generated on request of the page, and validated on submit.

It’s also good practice to ask for a password again on secure pages, like a change password form. This is an effective method against CSRF.

If All Else Fails
You’ll probably never end up with a 100% secured system, so it’s a good idea to mitigate damage if your websites security is breached.
For example, do not safe passwords as plain text, but use some sort of hashing or encryption ( MD5, SHA-1 ).
It’s also good practice to create full backups frequently, so that you can always restore your website fast.

ALWAYS BE PREPARED FOR THE WORST.

 Advertentie
Eenvoudig geld verdienen met je RPG game? Lees er alles over op www.targetpay.com
   Mark V, Particulier
2 nov 2008 09:04 
Looks good. All beginners should pay attention to these security issues. It's better to learn it at the start and do it right as you go on, then having to learn it afterwards (or even by experience when a "hacker" does take advantage of your site).

Good article

PS steel = staal, steal = stelen

   Stefan van Elsas, Particulier
2 nov 2008 13:10 
Typo =)

   Rick van B., Powergen
2 nov 2008 20:12 
A little addition to your story might be using salted passwords.

In example : user has password named : tBFoRuM6

We take the password string and put some random anywhere in the text. 'tb' + 'salt' + 'FoRuM6'.

Eventually when reading the password the program will know which part is salt.

When the password gets hacked they still won't know the real password.

It's always a good idea since MD5,SHA-1 passwords can sometimes be found in rainbowtables.

   Erwin de Bruijn, Double Media v.o.f.
2 nov 2008 22:12 
Rick normaly they use salt and pepper so you get: salt . password . pepper

   Niels v.k., Particulier
2 nov 2008 22:21 
Nice work!

   Verwijderde deelnemer
3 nov 2008 00:03 
I really do not support this tutorial.
Use of quotes, tags, style are totally wrong.

Please take a look at the Pear Coding Standards to get an idea of the PHP standards:
(Log in om link te zien!)

And for HTML just use (Log in om link te zien!)

   Stefan van Elsas, Particulier
3 nov 2008 02:39 
Note that this article is about PHP Security and not about coding standards. Regarding the quotes, it's copied directly from Word, so no wonder the quotes are wrong.

That said, I know most of the Pear coding standards and I don't like them that much.

I wonder how and why you judge an article about PHP Security on it's coding style. Given the fact that this forum does not indent code and does not hightlight code. In fact, it doesn't even try to display code correctly (which is not a bad thing).

     Aangepast op 03-11-2008 06:05 door Stefan van Elsas
   Richard O., Particulier
3 nov 2008 08:15 
That, and Pear Coding Standards are not "the PHP standards".
Pear != PHP

Salts are usually applied to the password before encryption.
For instance password 'welcome' has MD5 hash 40be4e59b9a2a2b5dffb918c0e86b3d7 which can be easily found using Google.

By applying a salt '1234' and then calculating the MD5 hash of '1234welcome', the hash will be 4c390e6b64b704f324eedb37918ed438.

Both the hash and the salt are stored. When a password needs to be checked, the entered password is prefixed with the salt, hashed, and compared to the stored hash.


   Verwijderde deelnemer
3 nov 2008 14:52 
There are no standards, but Pear is a highly recommended standard.
And besides is putting spaces after a html property just wrong.

Many security wholes are because of wrong coding styles. And maybe even worse, it can't be a problem to solve it by a theird party because of the 'strange' code.




 
© Copyright TargetMedia 2001-2012 | Mobile | Premium SMS | Micropayments | Muziek downloaden | Ringtones Bekijk bezoekers statistieken RSS feed