Website Security (Cross-Site Request Forgeries)

A cross-site request forgery (CSRF) is an attack that attempts to cause a victim to unknowingly send arbitraryHTTP requests, usually to URLs requiring privileged access and using the existing session of the victim to determine access. The HTTP request then causes the victimto execute a particular action based on his or her level of privilege, such asmaking a purchase or modifying or removing information.
Whereas an XSS attack exploits the user’s trust in an application, a forged request exploits an application’s trust in a user, since the request appears to be legitimate and it is difficult for the application to determine whether the user intended for it to take place. While proper escaping of output will prevent your application from being used as the vehicle for a CSRF attack, itwill not prevent your application from receiving forged requests. Thus, your application needs the ability to determine whether the request was intentional and legitimate or possibly forged and malicious.
Before examining the means to protect against forged requests, it may be helpful to understand how such an attack occurs. Consider the following example.
Suppose you have a Web site in which users register for an account and then browse a catalogue of books for purchase. Again, suppose that a malicious user signs up for an account and proceeds through the process of purchasing a book from the site. Along the way, she might learn the following through casual observation:
• She must log in to make a purchase.
• After selecting a book for purchase, she clicks the buy button, which redirects her through checkout.php.
• She sees that the action to checkout.php is a POST action but wonders whether passing parameters to checkout.php through the query string (GET) will work.
• When passing the same form values through the query string (i.e. checkout.php?isbn=0312863551&qty=1), she notices that she has, in fact, successfully purchased a book.
With this knowledge, themalicious user can cause others to make purchases at your site without their knowledge. The easiest way to do this is to use an image tag to embed an image in some arbitraryWeb site other than your own (although, at times, your own site may be used for such an attack). In the following code, the src of the img tag makes a request when the page loads.

<img src="http://example.org/checkout.php?isbn=0312863551&qty=1" />

Even though this img tag is embedded on a different Web site, it still continues to make the request to the book catalogue site. For most people, the request will fail because users must be logged in to make a purchase, but, for those users who do happen to be logged into the site (through a cookie or active session), this attack exploits the Web site’s trust in that user and causes them to make a purchase. The solution for this particular type of attack, however, is simple: force the use of POST over GET. This attack works because checkout.php uses the $_REQUEST superglobal array to access isbn and qty. Using $_POST will mitigate the risk of this kind of attack, but it won’t protect against all forged requests.
Other, more sophisticated attacks can make POST requests just as easily as GET, but a simple token method can block these attempts and force users to use your forms. The token method involves the use of a randomly generated token that is stored in the user’s session when the user accesses the form page and is also placed in a hidden field on the form. The processing script checks the token value from the posted form against the value in the user’s session. If it matches, then the request is valid. If not, then it is suspect and the script should not process the input and, instead, should display an error to the user. The following snippet from the aforementioned formillustrates the use of the token method:

<?php
session_start();
$token = md5(uniqid(rand(), TRUE));
$_SESSION[’token’] = $token;
?>
<form action="checkout.php" method="POST">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<!-- Remainder of form -->
</form>

The processing script that handles this form (checkout.php) can then check for the token:

if (isset($_SESSION[’token’])
&& isset($_POST[’token’])
&& $_POST[’token’] == $_SESSION[’token’])
{
// Token is valid, continue processing form data
}

SOURCE:ZEND PHP5 CERTIFICATION STUDY GUIDE

0 comments: