Avoiding cross site request forgery in your web apps

Google recently fixed a glaring vulnerability in gmail that allows an attacker to forward copies of all or some of your email to themselves by adding a filter to your gmail account. But not before someone lost their domain name to an attacker who then proceeded to try to sell it back to them for cash.

The gmail bug was a cross site request forgery exploit. The attack is incredibly simple. If a user is authenticated to a website, an attacker simply gets that user to load a URL that causes the user to effectively take some sort of action on that website. So by clicking a link in an email or on a website, or by simply loading up a malicious web page that contains an image URL with the correct query string parameters, an attacker can get an unsuspecting user to “do something” on a website they’re a member of.

Wikipedia has a good summary on CSRF and I recommend you read it if you haven’t already. Avoiding CSRF vulnerabilities in your web apps is easy: In all forms that require a user to be authenticated, simply reauthenticate them using some user-specific transient data. You could, for example, include a users session ID in a hidden form field and when the user submits the form check that the session ID in the form POST matches the session ID in the users cookie.

If your session ID’s change every time a user authenticates to your website, it effectively defeats this attack. For extra security you may want to either encrypt the session ID in the form’s hidden field, or set the hidden fields value to an MD5 hash of the real session ID.

The Google CSRF required a form POST which was only slightly more complex for an attacker to implement. But many CSRF attacks don’t require a POST and parameters can therefore appear in a URL query string. The effect of this is that your website can be exploited by one of your users simply loading an image on a malicious web page or in a malicious email.

4 thoughts on “Avoiding cross site request forgery in your web apps

  1. Pingback: -= Linkage 2007.12.28 =-

  2. Sure, but many people don’t use random session ID’s but instead guarantee uniqueness by using an autoincrement field in a database. On a low traffic site an autoinc field is very easy to guess, hence the suggestion of encryption or hashing.

  3. “set the hidden fields value to an MD5 hash of the real session ID.”

    If the session id is randomly generated, it doesn’t make sense to encrypt it. A random string is a random string, no matter how it looks. The only possible way a md5 is more secure, is the size of the text. Then the attacker would need more time to crack it using brute force.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.