Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to best prevent CSRF attacks in a GAE app?

So, what is the best way to prevent an XSRF attack for a GAE application? Imagine the following:

  1. Anyone can see a user's public object, and the db.Model id is used in the request to figure out which object to show. Malicious user now has the id.
  2. Malicious user creates their own object and checks out the delete form. They now know how to delete an object with a certain id.
  3. Malicious user gets innocent user to submit a delete request for that user's object.

What steps can I add to prevent #3? Note that when I say ID, I am using the actual ID part of the key. One idea I had was to use the full key value in delete requests, but would that prevent a malicious user from being able to figure this out? As far as I know, the key is some combination of the model class type, the app id, and the object instance id, so they could probably derive the key from the id if they wanted to.

Any other ideas? Jeff wrote a post about this, and suggested a couple methods - a hidden form value that would change on each request, and a cookie value written via js to the form. I won't want to exclude non-javascript users, so the cookie solution is no good - for the hidden form value, I would have to do a datastore write on every request that displayed a deletable object - not an ideal situation for a scalable app!

Any other ideas out there?

like image 662
Chris Marasti-Georg Avatar asked Oct 13 '08 18:10

Chris Marasti-Georg


2 Answers

When you generate the page that lets the user delete an object, generate a random token and include it in a hidden form field. Also set a HTTP-only cookie with that value. When you receive a delete request, check that the random token from the form and the value from the cookie match.

Your random token shouldn't just be a random number. You should encrypt the combination of a random number and the user's identity, to make it difficult for attackers to forge their own tokens. You should also use different encryption keys for the value stored in the form and the value stored in the cookie, so if one of the tokens does leak, it is still difficult for an attacker to forge the other token.

This approach verifies that the delete request originates from your form, by the presence of the security token in the form; and doesn't require writing to the datastore.

This approach is still vulnerable to cross-site scripting attacks, where an attacker could retrieve the hidden value from the form or submit the form, so thoroughly test your site for cross-site scripting vulnerabilities. This approach is also vulnerable to "clickjacking" attacks.

like image 150
Dominic Cooney Avatar answered Nov 10 '22 09:11

Dominic Cooney


Simple: Check the referer. It's (deliberately) impossible to set this using Javascript, HTML forms, etc. If it's blank (some proxies and browsers strip referers) or from your own site - or more specifically from the expected source - allow it. Otherwise, deny it and log it.

Edit: Jeff wrote a followup article with a couple of ways to prevent CSRF attacks.

like image 43
Nick Johnson Avatar answered Nov 10 '22 09:11

Nick Johnson