Preventing Cross Site Request Forgery (CSRF)

XSRF, also known as cross site request forgery or CSRF, can be used to trick an authenticated user to perform actions they did not intend on your site. It takes advantage of the trust your site has for users already logged in.

What is Cross Site Request Forgery?

In order for this attack to be successful, your site must track users logged in with cookies, and they must be logged into your site at the time they visit a site or click a link which the attacker has provided to the user.

Often, an attacker does not actually need to convince users to physically click on a link they provide to trigger an attack. There are a variety of tricks employed which can cause a user to 'click' the attacker link. For instance, any site an attacker has access to, such as a forum or social network account, may include special image tags which actually call include the link to the target site. The link can be crafted to force the users browser to execute an action using the session credentials they logged in as, along with any effects of submitting that link. In this way, when the page loads, the user has 'clicked' whatever link is placed in the image tag, and the authenticated action has been performed without the users permission.

If the targeted user happens to be an administrator, this attack could potentially allow an attacker to gain control of an entire web application.

Imagine the following attack scenario:

  1. Bob is browsing mysite.com, and is logged in as a user.
  2. Mysite.com has a button which, when pushed, will send an e-card to all of Bob's saved contacts automatically with a link.
  3. While Bob is on mysite, he has a question about some features, and goes to his favorite forum about mysite - mysiteforums.com.
  4. He opens an interesting post by another user. This post contains an image tag looking something like <img src='http://www.mysite.com/send-e-cards'/>
  5. Bob's browser tries to fetch the image, and sends Bob's authentication cookie along with the request to mysite.com/send-e-cards.
  6. Mysite.com receives the request from Bob to send the e-cards, and so sends the ecards.
  7. The attack is successful, even though Bob never clicked on the send button!

This kind of attack was successfully used to spread worms through both MySpace and Facebook. The nature of the attack makes it easy to self-propagate on sites where users may post profile information.

Impact to Your Site & User Base

Impact for XSRF can be minimal or critical depending on the nature of your site. It is classified as lower during our scans due to the lack of additional information needed to make a proper security assessment, which can only be made by site owners.

XSRF could potentially be used for anything ranging from tricking a user into changing their password on your site, to withdrawing funds if the site is a bank allowing transactions. You should prevent XSRF possibilities by following the recommendations in the solutions section.

How to Prevent CSRF Attacks

Preventing CSRF requires changing how all GET and POST requests work on a site, to ensure that users who are requesting an action have actually done so, and were not tricked into doing so. Because of the way an XSRF attack works, the attacker never has access to the cookie data stored on the targets machine, and this fact can be used to craft a defense.

Taking advantage of this, site owners can generate unique values on all forms, such that an attacker would not be able to guess ahead of time what to submit in the POST or GET request. This is called a nonce, or unique random value.

To implement this, you have to include a few logic layers in your application.

  1. Include a hidden form field on all forms of your site which are required when a user is logged in. For example purposes, let's call it the nonce.
  2. Include the nonce value in the users session variables, so that they have a copy.
  3. After every POST or GET evaluation you want to protect, make sure that the nonce from the browser (session) matches the nonce from the form (GET/POST value)
  4. If they do not match, then the page may have been submitted fraudulently (XSRF)
  5. The nonce may be generated new for each form, or stored server side in a database. Be aware that if it is generated new each time, you may face issues with users back button functionality, or multiple tabs, although this ius less work then storing it server side.

Here is a code example in PHP, without saving values to a database:

The first page (form or submit page, where a user would take the action)

<?php
  //start the user session (set session cookie)
  session_start();
  //generate nonce - this nonce will be used for this session only, using random values and the time
  $nonce=hash("md5",rand().time().rand());
  echo "<br />Nonce: ".$nonce."<br />";
  $_SESSION['nonce']=$nonce;
?>
<!-- Now create the form, and include the same nonce we generated above-->
<form name="do_some_action" action="completeAction.php" method="POST">
  <input type="hidden" name="nonce" value="<?php echo $nonce?>"/>
  <input type="submit" value="do Action"/>
</form>

The page where the action is performed, after a user clicks a button.

<?php
  //start session
  session_start();
  //get the POST nonce
  $post_nonce=$_POST['nonce'];
  //get the session nonce
  $session_nonce=$_SESSION['nonce'];
  //make sure to validate the post input to prevent other types of attacks! Not shown here for brevity
  if($post_nonce===$session_nonce)
  	echo "Request is safe!";
  else
  	echo "Data might be stolen!";
?>

Additional Resources

Prevent CSRF on Your Website

Golem Technologies includes numerous different server setting scans to help you reduce your exposure to attack with thorough security scanning, including cross site request forgery and other types of cross site scripting attacks. See how the Golem Scan can help your business today.