
We are approaching the finishing line for TYPO3 Flow 2.0 - the feature set is frozen now, apart from one important addition which is currently in the works: support for "safe request methods" and removing CSRF tokens from URIs. We didn't plan for this and it comes at pretty short notice before the Inspiring Flow conference. But it's doable, if we can quickly raise some funds for two days of development. If you ever cursed about CSRF tokens in your links ... read on.
Since its first version Flow comes with built-in protection against Cross-Site Request Forgery attacks: an attacker prepares a link which does something harmful - for example deleting a customer record - and sends it to a user who unintentionally clicks the link while being logged in. TYPOFlow protects links to method calls which are protected by a policy by requiring a CSRF token to be sent along with the request. This token is bound to an active user session which means that if you want to execute a CSRF attack you additionally need to know the user's session id and a server-side secret or get ahold of a "hot" link.
Buckle up – it's only safe when you use it
Consider a deleteAction() in one of your action controllers which is protected by a security policy. When you let Flow generate links to this action in your Fluid templates, a CSRF token is appended, which results in links like these (please don't click it, it would delete all my blog posts):
http://robertlemke.com/en/blog/posts/delete?__csrfToken=801420a0d4740a438801546601cb17
Now, if you click such a link without a matching, active user session, Flow's security framework will block the request. That's great ... unless you want to send such a link to your colleague or post it on App.net. Unfortunately, Flow cannot know in advance what you are going to do with the link: will you only use it for a read-only action or is it really a link which is potentially harmful?
Having CSRF tokens in your URIs is a hassle. That's why the @SkipCSRF feature has become wildly used in many Flow projects. Bummer.
If it's safe, you can consider it safe
If Flow knew which request can be considered safe (that is: it might show sensitive data - which is no problem, because the logged in user would see it - but doesn't change or destroy any data) it could skip checking for a CSRF token right away. Fortunately there is a definition for "safe" requests, in our favorite spec, RFC 2616:
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
If we support (and partially enforce) this paradigm in Flow (which we will), we can assume that a GET request is not vulnerable to CSRF attacks and thus don't have to generate CSRF tokens for these requests. In fact we will never have to add a CSRF token to a URI ever again because:
- GET requests are "safe"
- POST, PUT, ... requests can submit a CSRF token in their message body, submitted via a hidden field in a form or similar
- DELETE, ... requests can submit a CSRF token through a special message header
Implementing safe and frustration-free requests
TYPO3 Flow 2.0 will support the notion of safe request methods in these ways:
- CSRF tokens won't be checked for "safe" requests
- CSRF tokens still are required for "non-safe" request methods to methods protected by a policy
- the persistence layer will not persist any changes (with persistAll()) for GET requests
- the link view helpers and UriBuilder won't add any CSRF tokens anymore
- the form view helper will add a token to their set of hidden fields
Making it happen
I already implemented a proof of concept for safe requests, but in order to get rid of the whole aspect which renders tokens into URIs, there's a lot more work necessary. I'm way out of funds for doing this on my own currently (which is a longer story for a night at the bar), so in order to make this happen we need to crowd fund the feature.
Here's the deal: if we can raise 600 - 800 € (more always possible), I can implement this feature in time for the conference end of this week. Just leave your offer in the comments and I'll get back to you. And if you can spend some more: the Flow team urgently needs funding for some more hours of code reviews and release management - any help appreciated.
Jochen | 17.04.2013
Only thing hearing from you recently is " I'm way out of funds for doing this".
It's sad.
Robert Lemke | 17.04.2013
Jochen, yes it is. Until today, in 2013 the development and coordination of the Flow project has been exclusively funded by the team members. They are freelancers and although they invest literally hundreds of hours in to the project, there is only so much they can afford to do.
I wouldn't ask for funding if I could fund it myself. It's not about earning a few bucks extra but about being able to to run the Open Source project and at the same time pay your bills.
Karsten Dambekalns | 17.04.2013
Jochen, feel free to have a chat with me during Inspiring Flow. You can check my personal bank account and this year's time logs and afterwards you tell me about the funds I should be using, ok? And I guess Robert would do the same.
It seems everyone thinks we must be fully booked for paid jobs all the time. It's sad.
Thomas Schikarski | 17.04.2013
Unfortunately, I cannot afford much at the moment, however, improving security by making it userfriendly is always a good move. +50
Tomas Norre Mikkelsen | 17.04.2013
Hi,
I would be glad help funding an amount, not posible for big amount, but small amount may help to.
Feel free to contact me.
Patrick Broens | 17.04.2013
Jochen, please investigate in the current funding before adding such a comment. I would be glad to help with funding safe requests with 100,-
Carsten Bleicker | 17.04.2013
+100, more isnt possible because i am a one man show. but it would be wonderfull if typo3 agencies donate the same small value for each employe? Go!
Robert Lemke | 17.04.2013
My sincerest thanks to you guys for your support!
In case we can raise more than is needed for this feature, we'll use the money for reviews of contributions in the Flow / Neos review queue.
Christopher Hlubek | 17.04.2013
Hi Robert,
thanks for taking the step to finally implement this. I know we talked about this already a few times (time is limited so I fully understand that some funding is needed!). This also is a nice performance improvement when building a lot of links! Also not calling persistAll on read-only requests will save quite some time for most requests.
I'm happy to fund this with another 200€.
Jochen Weiland | 17.04.2013
You can send me an invoice for 200 (+VAT). Btw, the other comments are from a different 'Jochen'.
Robert Lemke | 17.04.2013
@Christopher - thanks a lot!
@The Real Jochen: thank you, I hoped that it wasn't you ;-)
Georg Ringer | 17.04.2013
650€ already donated, awesome!
I like those ideas of a fast crowdfunding for single features as it is fast to implement, fast results and still not that much money.
Robert Lemke | 17.04.2013
Thanks to all of your support we could just merge the new feature which I worked on during the last couple of days:
http://forum.typo3.org/index.php/t/195682/
https://review.typo3.org/#/c/19989/
Also thanks to the Flow team for reviewing the patches!
Jacob Rasmussen | 17.04.2013
Hi Robert,
I'm also willing to spend 200€ on this, so you can spend the necessary amount of time.
Rgds
Jacob
Henjo | 18.04.2013
+ 50