2

I'm wondering why Rails form Authenticity Tokens last the entire session instead of being generated uniquely per each submission.

I'm coming from web2py, where forms are generated with unique one-time tokens called _formkey. The formkey automatically prevents duplicate submissions resulting from double-clicking, back-button caching, etc.

In Rails, you apparently have to deal with the double-submission problem yourself (See https://stackoverflow.com/a/4683161/165673). It seems to me that one-time Authenticity Tokens would solve this problem, as well as being more secure?

Community
  • 1
  • 1
Yarin
  • 173,523
  • 149
  • 402
  • 512
  • 2
    In particular, I think the one-time token approach is more secure against the [BREACH attack](http://breachattack.com/). – Anthony Sep 06 '13 at 17:01

1 Answers1

3

One token for entire session is easier to implement. Think about a case where you have two opened tabs with forms.

One token for session is as secure as one-time token solution. At least as the protection against CSRF attacks.

In Rails, you apparently have to deal with the double-submission problem yourself

There is out of the box solution for that. Read about disable_with option. Of course all requests that modify data should be sent via HTTP POST, not GET.

lgowin
  • 81
  • 2
  • @Igowan - Dunno if the easier to implement argument flies. web2py does it, and can easily handle multiple forms per page / across tabs (unique tokens actually make this easier i think). Regarding `disable_with`, that's a client-side solution- handy for ux but not a reliable way to prevent double submissions the way a tokenized-solution would. – Yarin Sep 06 '13 at 19:25
  • @Yarin I use `disable_with` for many years and it works great. I don't understand what your problem really is. – lgowin Sep 10 '13 at 16:17
  • @Igowin- `disable_with` won't help you with ajax form submissions that get triggered programmatically, or with cached forms that get re-hit after pressing the back button. If the integrity of your data is at stake you can't rely on view-based enforcement. – Yarin Sep 11 '13 at 15:47
  • @Yarin In Rails data integrity is secured by the models layer. You can do this also using db constraints and checks. `disable_with` should be used to protect against double-submission problem - when someone accidentally double clicks submit button. – lgowin Sep 13 '13 at 16:37
  • 1
    @Igowin - "In Rails data integrity is secured by the models layer" - You're right, good point. I may have been hung up on an imaginary problem.. – Yarin Sep 14 '13 at 16:14