On 6/4/10 09:28 , Andreas Jung wrote:
  recommended approach for
> protecting a BFG app against XSS and CSRF?

Below is the code I use. The basic idea is that my users have a 'secret' 
attribute which is reset every time they login. This value is included 
in all forms in a hidden csrf_token field. I then used a subclass of the 
standard formish Form class which validates the CSRF token. This works 
well and is easy to use. The only slightly tricky bit is that you need 
to make sure you don't reset the secret if someone submits two logins 
forms in parallel, so make sure you only reset the secret if the user 
was anonymous before.


def currentUser(request):
     """Return the currently :obj:`capos.model.account.Account` , or
     `None` if the current user is anonymous."""
     policy = request.registry.getUtility(IAuthenticationPolicy)
     userid = policy.authenticated_userid(request)
     if not userid:
         return None
     return meta.Session.query(Account).get(userid)

def checkCSRF(request):
     """Check if the request has a valid CSRF token."""

     if user is None:
         return True

     if [user.secret]==token:
         return True

     log.warning("Invalid CSRF token from account %s (id=%d): %r",
                 user.login, user.id, token)
     return False

class CSRFForm(formish.Form):
     """Base class for forms which verifies CSRF tokens. Tokens have
     to be passed in as a HTTP POST parameter called `csrf_token`.
     GET requests are not allowed to prevent tokens from appearing in
     proxy or webserver logfiles."""

     def validate(self, request, failure_callable=None, 
                  skip_read_only_defaults=False, check_form_name=True):
         if not checkCSRF(request):
             raise Forbidden("Invalid CSRF token")

         return super(CSRFForm, self).validate(request, failure_callable,

Repoze-dev mailing list

Reply via email to