On Wed, Oct 20, 2010 at 04:11:16AM -0700, James wrote:
> Hi,
> Is there best practice to avoid CSRF attacks on TG2 servers?
> 
> The options that spring to mind are:
> - side-effecty calls must be POST form submissions (and check the HTTP
> method in the server method)
> - add an unguessable token to side-effecty GET requests
> 
> For the latter, I'm guessing some unique ID from the session would be
> best - any tips on what to use specifically?
> 
For all applications written in Fedora, we've created a couple of CSRF
protecting identity modules (for TG1) and a CSRF middleware for TG2.  It
works by adding a parameter _csrf_token this can be manually added via
a form parameter or via a get parameter.  We override tg.url() with
a version that can add the token to a url.  This makes moving from "normal"
TG apps to the csrf protected apps pretty transparent (You only need to do
some work if you are using tg.url() inside of your controllers, for
instance, to send out an email).

The token is a hash of the normal tg session id (tg-visit in tg1).  This
lets us verify the request without doing a db lookup but has the side effect
of being valid for as long as the tg visit session is valid.  ie: If you
copy and paste a link that includes your _csrf_token then you are vulnerable
for as long as you have the same tg-visit.  If someone knows of a way to
fix that I'd appreciate knowing :-)  The reason we hash it is since it could
go through the get parameter, it could end up in http logs so we want to
prevent the unhashed value from entering there (you need both the session
cookie and the csrf token to get access but since you can generate the token
from the session cookie value we need to protect the session cookie more
stringently).

If the user has a valid cookie but an invalid or missing csrf token, they
are treated as logged out -- except that if they go to the login page, that
page is set up to detect this and log them in by just clicking a button on
the page.  We choose to make everything protected by the token + session
cookie rather than allowing people to be logged in to view information only
because it errs on the side of security.  If we went the route of marking
which requests are data-changing and only requiring the token there, we felt
it would be inevitable that someone will forget to mark a function that
makes changes.  By linking it to being logged in in this manner, we make it
so that the programmer can't leave a page insecured.

Documentation for the TG1 provider:
https://fedorahosted.org/releases/p/y/python-fedora/doc/CSRF.html

Documentation for the middleware:
https://fedorahosted.org/releases/p/y/python-fedora/doc/faswho.html#module-fedora.wsgi.csrf

Code is LGPLv2+ and its here:
http://bzr.fedorahosted.org/bzr/python-fedora/python-fedora-devel/files/head%3A/fedora/

lmacken and I wrote the majority of the code if you're interested and need
some help with it.

-Toshio

Attachment: pgpMwPWLhnFyC.pgp
Description: PGP signature

Reply via email to