18

Cross-site request forgery is common on web now a days. I am facing this in my own site deployed on Google App engine. I got to know this by examining access logs. Is there any XSRF/CSRF library or other solution available for App engine that I can use. And, how much load it will add to my site?

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
Gagandeep Singh
  • 5,755
  • 4
  • 41
  • 60

3 Answers3

11

I use this code called from basehandler's init request function

def init_csrf(self):
    """Issue and handle CSRF token as necessary"""

    self.csrf_token = self.request.cookies.get('c')
    if not self.csrf_token:
        self.csrf_token = str(uuid4())[:8]
        self.set_cookie('c', self.csrf_token)
    if self.request.method == 'POST' and self.csrf_protect \
        and self.csrf_token != self.request.get('_csrf_token'):
        raise CsrfException('Missing or invalid CSRF token.')

I took it from Facebook's example canvas application includes code to handle crsf. I did not practically test it much but I include it in my project since I have a canvas application for Facebook that runs in FB as an iframe. It makes every request handler have an instance variable that you can set to false if it generates an exception for normal cases.

I didn't yet test it thoroughly but this is the material I have about CRSF tokens for Google App Engine in python. If you like to check out the details exacly how I'm learning how to use it these days you may clone my repository.

Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • 3
    Actually, the cookie approach to XSRF is known to be flawed and not recommended. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Prevention_Measures_That_Do_NOT_Work – Wes Alvaro May 03 '13 at 17:35
6

Maybe you can try to use the Django's contrib csrf protection middleware. Not sure that it will works out-of-the-box in AppEngine but it worth a shot.

Stan
  • 8,710
  • 2
  • 29
  • 31
5

I made a decorator:

def csrf_protected(handler):
    def inner(self, *args, **kwargs):
        token = self.request.params.get('token')
        if token and self.session.get('csrf') == token:
            self.session['csrf'] = uuid.uuid1().hex
            handler(self, *args, **kwargs)
        else:
            self.abort(400)
    return inner

Have token in template and session

milan
  • 63
  • 1
  • 4