Proposal for cookbook CSRF example #2

Open
wants to merge 1 commit into
from

Conversation

Projects
None yet
2 participants

thedod commented Mar 11, 2011

Please see commit message and example

Nimrod S. Kerrett Added a cookbook example of simple CSRF protection
I know it's not perfect:
* It's not as tightly integrated into web.py as it could have been
  (e.g. creating a form.Csrf field class or adding an application
  processor for *all* POST methods that *don't* have a @no_csrf_check
  decorator)
* Since we're only keeping a single csrf_token, if you open 2 tabs
  with forms, and then try to post both, the second time would be
  detected as a CSRF attack (hence the spiffy 400 error).
Still - it seems to be short and working, and it's better than not having
CSRF protection at all. Once a more complete solution comes along, I'll
be sure to adopt it.
a862368
Contributor

aaronsw commented Mar 11, 2011

Shouldn't this code be put into web.py and then the Cookbook page can just tell you how to use it?

thedod commented Mar 12, 2011

You mean extending web.py itself?
I can't do it at the moment, not only because I'm not a web.py expert, but also because all my free time goes now to my web.py application (after I write it, I hope I'll know web.py better :) ).

Also, my solution is bare-minimum and not suitable as a web.form feature (where I guess it would belong):
As @intellectronica points out, best would be if csrf_token() could generate more than a single token (to minimize the "stale browser syndrome"), but then we'd need to garbage-collect them by age or something.
This is doable, but - like I said - would require some thought by people who know web.py better than me.

On the other hand: if anyone (e.g. you) opens a CSRF web.py branch, I'd be glad to git submodule and alpha-test it in my app (will hopefully be up on github by the end of the month).

Contributor

aaronsw commented Mar 14, 2011

Where's intellectronica's comment?

thedod commented Mar 14, 2011

It's at https://gist.github.com/857297#gistcomment-23002
Although @intellectronica suggests to bind csrf tokens to URLs, it might be a problem if I have 2 tabs open in the sam url (e.g. add_blog_post").
Maybe csrf_token() can simply generate a new token each time. We should keep the tokens in a set (to make the tests at POST efficient), and also keep them in a fifo list (flood control: if len>MAX_TOKENS, we pop oldest token from the list, and also delete it from the set).
Since there could be a template that renders many forms, csrf_token() can be smart and only generate a new token if it's the first time it's being called during a request (and return the same token in subsequent calls).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment