Thursday, June 25, 2015

Protecting against CSRF

CSRF is a quite common and dangerous attack that many websites are not protected against. The attack can be used to perform actions on website with a logged in user.
To do the attack the attacker need to no what should be sent in a POST request and to URL to post, to perform an action. An action being for example. Creating a new user account.

Lets say the following is posted from a form to create a new account.

Name             Value
name              Carl
telephone        54865123
password        123456

The password is an example of commonly used passwords =)

The form is posted to a to the path http://www.mysite.com/users/createAccount

The attack can be done as follows.


  1. The attacker creates a page on his website like this.
  2. <html>
    <head>
    <title>My evil page</title>
    </head>
    
    <body onload="javascript:postForm()">
    <script language="JavaScript">
    
    function postForm()
    {
            document.form.submit();
    }
       
    </script>
    <form method="POST" name="form" action="http://www.mysite.com/users/createAccount">
    <input type="text" name="name " value="Carl"/>
    <input type="text" name="telephone" value="54865123"/>
    <input type="password" name="password" value="password"/>
    </form>
    
    </body>
    </html>
    
  3. The a link to a page is then be sent to the victims email. When the victim clicks, the form is posted and the action is excecuted.


Some of you might think that this wont work because your site has a login. But it the victim is logged in when the link is clicked the form will be posted using the authenticated session. Thus bypassing all login.

So you can see this is a problem. With a little knowledge of the internals of the site, an attacker can make a victim make whatever actions. And because the action is done with the victims session it can be hard to track the attack.

The way to protect against this is by putting a hidden input in the form, containing an unpredictable value stored at the server. For example a random number. Every session should have a unique value. The best is to let every request have unique value

<input type="hidden" name="CSRFToken" value="<?= $token ?>"/>

Because the attacker can't know the value in the response, all you need to do on the server is to control that the value you get in the post request is the same as the one stored on the server.

For more information, tools and tips have a look at OWASPs page for CSRF http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

I would also recommend the OWASP top 10 publication. Witch describes the top 10 security threats to web applications and how to protect against them.

No comments:

Post a Comment