-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make authenticity token length a fixed value #1181
Conversation
fdd474d
to
65699c4
Compare
Ugh, sorry haven't had time to look into this issue lately. How come you're using class variables instead of default options? Re naming, we already have Also just as a reflex, this patch is really hard to grok by the diff because there's a lot of changing of method visibility. So please give me some time to review this more thoroughly! Thank you for your patch!! |
Yeah, sorry about big diff. The reason for the class variables for the session key and token length stems from the need to offer a way get a masked authenticity token when building forms in a view. So you could do that now by calling:
I think most would want to put that in a helper. Previously you would just use the value To avoid using class variables, there are a couple options I can think of:
|
16ba3f4
to
589c5e2
Compare
So I guess, prior to Rails adding BREACH mitigation, the tokens were compatible. And since then we've been promising a lie, because they were no longer compatible. I did however see something about keeping support for existing session tokens with the Rails patch, but I'm not sure if that affects us. If that's true (P.D.I.), and we're both using different BREACH strategies (e.g. the token length is different, etc) then I would almost say let's just use the major version bump to break that promise and update the documentation for Sinatra. I have a feeling supporting shared sessions between sinatra and Rails will prove to be an ongoing effort when it is unclear how many people rely on this feature, and could implement it themselves. |
Yes, once Rails started using masked tokens in forms, rack-protection would not have been able to handle them. You're right though, Rails would still be able to compare the unmasked authenticity tokens so a Sinatra app could directly access session[_:csrf_token] and that would work. I think using the major version bump to break the promise of compatibility is good. Or at least the idea of syncing the values of the two different authenticity tokens stored in the session. I've updated the PR to use a fixed value for the session key and token length. This makes the helper method for fetching a masked version for the token easy to use:
Since the BREACH protection strategy and token length does currently match up with Rails the following code could be used to get a masked version of the Rails authenticity token:
If you don't think it's a good idea to go down that road though, I could remove that optional parameter. |
I'm almost 90% sure we should just break the promise, but I'd like to get some feedback to see if anyone is actually using this feature. Maybe @rkh knows? Sinatra isn't designed to be a middleware, it has it's own router and other utilities that make it set apart from the rest of your stack, be it Rails or whatever. However, RP is designed to be a middleware, but at the core of it is session protection. We can't possibly hope to maintain compatibility with every other session protection out there, so in my opinion if you want to protect a session you should decide before hand how that session will be shared or not -- and which protection library to use. |
3f734f4
to
50e64e6
Compare
@zzak I'm all for that suggestion 👍 I do think I'd still rather see the token length a fixed value of 32. It keeps things simple and it makes sure a secure value is used. See: http://security.stackexchange.com/questions/6957/length-of-csrf-token Also, this way If that's good, I'll clean up these commits. |
👍 |
33a915d
to
0709f8e
Compare
Rack::Protection::AuthenticityToken.token(session) can now make sure that an authenticity token is set in the session before returning a masked version of the token. Any Rack app that shares the session can use this method when building a form for an app that uses rack-protection. Removes references to Rails compatibility as rack-protection 2.0 officially breaks that promise.
0709f8e
to
4f1bdba
Compare
Adds a new configurable option
:csrf_key
that allows the csrf session key to be configured to be shared with other frameworks.For instance it could be changed to
:_csrf_token
to be compatible with Rails. This way Sinatra forms could be sent to Rails actions and pass CSRF protection and vice versa (as long as the session is shared).use Rack::Protection, :csrf_key => :_csrf_token
@zzak let me know if you think any option names or method names need changed. I also tried to reduce the public API a bit in this update.