TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Advanced PHP Programming (http://www.talkphp.com/advanced-php-programming/)
-   -   Cross-Site Request Forgeries (http://www.talkphp.com/advanced-php-programming/1063-cross-site-request-forgeries.html)

Karl 09-10-2007 11:39 AM

Cross-Site Request Forgeries
 
Cross-Site Request Forgeries

Here's a short, concise article on CSRF. A cross-site request forgery (CSRF) is an attack that attempts to exploit an applications trust in a user.

For this article I want you to visualise the following scenario.

A library has setup an online booking system where users can reserve books online. However, reservations for books that are not picked up will incur a penalty. This is where a malicious user may decide to have some fun.

In order to reserve a book the user simply sends the following request to reserve.php

Code:

reserve.php?book=12345&duration=14
The query string above would tell reserve.php to reserve the book with the ID 12345 for 14 days. With this knowledge an attacker could easily cause mischief by providing users with a link to your website, ordering any book they see fit. For example, a user could create the following image link:

Code:

<img src=http://www.library.com/reserve.php?book=99999&duration=99 />
This simple yet subtle image would take a user straight to the library website and reserve the book 99999 for 99 days. Now, although in this case this wouldn’t achieve much more than annoying a few people, the potential damage of CSRF becomes apparent. If this was an online ordering system the user could have easily ordered many items under a different users account.

CSRF attacks do require the attackers to target users who are already logged in, however, with today’s websites logins are usually remembered for long periods of time so this usually isn’t a problem.

How to Protect Yourself

In order to combat CSRF you must determine whether a request is coming from a valid or malicious user. One common technique to achieve this is through the use of tokens. Let’s say, for example, that the following form is used to reserve a book:

Code:

<form method=”get” action=”reserve.php” enctype=”multipart/form-data”>
<input type=”text” name=”book” />
<input type=”text” name=”duration” />
<input type=”submit” value=”Book It!” />
</form>

Now, in order to protect this form, we should create a new hidden field and store a randomly generated token. For example:

Code:

<input type=”hidden” name=”token” value=”<?php echo $token ?>” />
Where $token would hold a randomly generated string. This token would also be stored in the user’s session or cookie. Then, on the reserve.php page we simply check the form token against the users token, if they match, we can assume the request is legitimate. If they don’t match then we assume that it’s an illegal request and we force the user to login again.

Village Idiot 09-10-2007 07:15 PM

You could also use POST for the book number and the number of days.

Karl 09-10-2007 07:55 PM

You could, but it wouldn't really offer you much more protection against CSRF. Malicious users can also forge a POST request just as easily as a GET, I just thought the GET method made the example easier to grasp.

Village Idiot 09-10-2007 08:08 PM

Quote:

Originally Posted by Karl (Post 1968)
You could, but it wouldn't really offer you much more protection against CSRF. Malicious users can also forge a POST request just as easily as a GET, I just thought the GET method made the example easier to grasp.

You cant forge POST requests from a remote server, the only way to put post data in is the form.

Karl 09-10-2007 08:28 PM

You actually can still do this type of attack using a POST it just isn't as simple as embedding an image, here's an example:

http://www.businessinfo.co.uk/labs/c...cks/holder.php

Village Idiot 09-11-2007 12:57 AM

Google's search uses get data, not post.

erect 09-11-2007 06:58 PM

Quote:

Originally Posted by Village Idiot (Post 1969)
You cant forge POST requests from a remote server, the only way to put post data in is the form.

Curl will let you post variables and will allow you to spoof your user-agent.

bluesaga 09-12-2007 02:22 PM

You can use standard Fputs to post variables, basically if you can change the header, you can change the POST and GET vars, cookies etc fairly easily.

Village Idiot 09-12-2007 08:10 PM

You cant fwrite (Fputs) a properly configured remote server, not with writing privileges anyway.

bluesaga 09-13-2007 04:23 PM

You can write to the HEADER quite easily though using the same function....

Tanax 09-29-2007 07:56 AM

So basicly, how would you do the check if the tokens match?

Karl 09-30-2007 01:02 PM

An exmaple would be to first set the token as the users cookie:

PHP Code:

$_SESSION['token'] = $iToken;

// Now create the form using this token 

And then on the next page, we simply check:

PHP Code:


if ($_SESSION['token'] !== $_POST['token'])
{
    echo 
'Tut tut, bad boy!.';


You would simply use code like that to check the token.


All times are GMT. The time now is 12:30 PM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0