[web-devel] Yesod change for 0.6: CSRF protection

Michael Snoyman michael at snoyman.com
Mon Oct 25 16:47:23 CEST 2010

Hey all,

This should probably go in a blog post (and it probably will yet), but
I wanted to get some quick feedback on an upcoming change for 0.6.
Greg Weber pointed out that Yesod currently has no Cross Site Request
Forgery (CSRF) protection, so I've made a patch that addresses this.
You can see the code on the ver0.6 branch on github[1], but here's a
bird's-eye view of the solution:

* Each session will be assigned a random, 10-character nonce.
* runFormPost will check for a _nonce hidden field and ensure that it
matches the nonce for the session. If not, it causes a FormFailure.
* runFormPost now returns a 4-tuple, containing the result, the form
xml, the encoding type and an Html value for the nonce hidden field.

You may be wondering why I don't just stick the hidden field directly
in the xml. The reason is that we don't know the type of the xml
value: it may be a FieldInfo, a Widget, a Hamlet, Html, anything.
Also, even if we knew the datatype, we don't know *where* to append
the nonce. For example, if the xml value is a collection of <tr> tags,
it would generate invalid markup to simply append an <input> tag

I've also added a runFormPostNoNonce which has the same behavior as
the old runFormPost. I've specifically renamed the unsafe version to
something wordier so that current code will be prompted to reconsider
whether or not to check the nonce. I know this may cause significant
code breakage, so I'd appreciate user feedback on this one.


[1] http://github.com/snoyberg/yesod/tree/ver0.6

More information about the web-devel mailing list