Using Rack HEAD causes CookieStore security warnings #7372

Closed
dlee opened this Issue Aug 16, 2012 · 44 comments

Projects

None yet
@dlee
dlee commented Aug 16, 2012

Rack::Session::Cookie accepts a :secret option in its initializer. The initializer stores that secret in an instance variable and uses it in the #set_session method to HMAC sign the data.

Rack HEAD added security warnings for when the Rack::Session::Cookie middleware is initialized without a secret.

This is causing the warning to show up because of the way Rails uses Rack::Session::Cookie:

Rails uses a subclass of Rack::Session::Cookie called ActionDispatch::Session::CookieStore that overwrites #set_session and #set_cookie to do its own signed cookie implementation using ActionDispatch::Cookies::SignedCookieJar (using Rack env "action_dispatch.secret_token" instead of the @secret instance variable). Since Rails doesn't need the @secret instance variable, it initializes ActionDispatch::Session::CookieStore without providing a :secret option.

To avoid the warning, we should just not use Rack::Session::Cookie. We're overriding a lot of the functionality for Rack::Session::Cookie anyway, to the point that its most important functionality (cookie signing) is not being used at all.

@steveklabnik
Member

Would you be interested in working up a pull request to fix this? You seem to have a pretty good handle on the problem.

@dlee
dlee commented Sep 21, 2012

@steveklabnik Is not using Rack::Session::Cookie the correct direction?

There's the other option of using Rack::Session::Cookie properly, at the cost of losing the ability to use ActionDispatch::Cookies::SignedCookieJar for the signing.

@steveklabnik
Member

I am not 100% sure what the right thing is to to, to be honest. I'm still wrapping my head around session code in Rails.

@dlee
dlee commented Sep 21, 2012

Can we get someone in Rails core who's familiar with Rack integration to chime in? What's our philosophy behind integration with Rack? Do we try to use as many standard Rack middleware as possible, or is that not a priority?

@steveklabnik
Member

That kind of question is better served by a post to the rails-core list. The chances of a reply in Issues is pretty low.

@senny
Member
senny commented Oct 13, 2012

@dlee I also suggest you start a discussion on the mailing list. The bug tracker is primarily used to track bugs and pull requests with attached code (for new features). For discussions the mailing list is better suited.

@steveklabnik should we close this ticket in favor of a post on the core-list?

@dlee
dlee commented Oct 13, 2012

@senny I can see how the discussion about "our philosophy behind integration with Rack" is better suited for a mailing list, but I still consider the main issue here to be a bug.

@homakov
homakov commented Oct 13, 2012

I would love to join. Rack stuff is tiny and can be rewritten
I actually was about to write encrypted session jar. Not signed, just encrypted with secret so you could not read it. WDYT about it?

@steveklabnik
Member

@tenderlove and @NZKoz , what is the behavior that's intended here?

@NZKoz
Member
NZKoz commented Oct 13, 2012

yeah, we need to avoid using the rack session subclass as this warning isn't relevant for us. It doesn't seem to give us much behaviour that we don't then turn around and re-implement.

A pull request for that would be a good start.

@homakov we intend to ship an encrypted cookie store with 4.0, and also start using the key derivation code rather than the raw secret, perhaps we can look into that once we've removed the rack subclassing?

@homakov
homakov commented Oct 14, 2012

@NZKoz good idea! anyone is on it or is it just future plan? I see more pros of 'encrypted' than in 'signed'. It will allow to develop database-less(stateless) applications - developer is sure that data from session is not readable/writable, each user is just carrying his own DB.
One thing - performance. Doesn't it look slower to decrypt every session everytime.. gotta check

@tehgeekmeister

Looks like the discussion here (that I wasn't yet aware of) makes #8792 not the appropriate fix for #8789. If I am up to the task of refactoring to what it seems the consensus here is (moving away from subclassing rack's session stuff), would that be a desirable pull request?

@guilleiguaran
Member

@tehgeekmeister yes, a pull request for this would be great

@NZKoz
Member
NZKoz commented Jan 8, 2013

Yes, we're subclassing where we don't need to. The rack guys have (quite reasonably) added a warning and our code is triggering it. You can safely disregard it.

As mentioned by @steveklabnik and @tehgeekmeister the preferred fix should be to stop subclassing inappropriately, and we'd like a pull request for that.

@tehgeekmeister

Just got my dev environment set up and tests runnable. Getting started on the changes now!

@tehgeekmeister

It looks like we're going to have to clone a lot of functionality from rack to do this. Seems like it might be better to maintain the subclassing. I'll happily do the work if everyone disagrees, but as the person doing it, it's starting to feel like a bad idea.

For now, I'll just keep going and get a pull request up so there's something explicit for people to look at, and see what I mean.

@colszowka

Maybe it would be nice at this point to team up with the rack team to figure out how it'd be possible to move all this custom functionality you're mentioning into rack itself and have Rails have nothing to do with the details of session and cookie implementation? Is there functionality in the whole rails cookie implementation that would not benefit rack apps in general?

@tehgeekmeister

There's some that I suspect other frameworks don't want to have. Some of it is around making autoloading work nicely (https://github.com/rails/rails/blob/cb3181e81e3a0e9d03450c7065fcc226e2e1731c/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb#L58 for example). Other stuff seems to be duplication, for example, the whole thing that's caused this is that rack now can handle cookie signing, which I assume it couldn't earlier, since rails has an implementation of that too.

I'm in favor of discussing with rack people as well. Seems like a good course of action. I'll dig into this more tomorrow and build up a list of duplications/points of tight coupling, since that will be useful whichever way we decide to go.

@NZKoz
Member
NZKoz commented Jan 8, 2013

The true goal is to avoid that error to be honest, it's caused because our session implementation just delegates to cookies.signed or cookies.encrypted depending on how it's configured.

Here's our set_session:

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb#L70-L72

Here's rack's

https://github.com/rack/rack/blob/master/lib/rack/session/cookie.rb#L131-L145

The main issue here's is we're calling super's initialize which is triggering an error even though we don't use secret.

If changing the messy subclassing isn't an option, then simply override initialize and pass the secret correctly, though the value will never be used, it'll avoid the warnings.

@mjtko
mjtko commented Jan 8, 2013

While @spastorino committed a workaround in cb3181e to suppress the message for now, I think the better fix is to subclass from Rack::Session::Abstract::ID instead of Rack::Session::Cookie, as we are providing our own cookie implementation in rails.

Here's my approach to do that: https://github.com/mjtko/rails/compare/fix;cookie-store-inheritance

If somebody on the core team could comment and shout if they think this looks reasonable, I'll open it as a PR.

/cc @tenderlove and @NZKoz

@athlite
athlite commented Jan 8, 2013

Quick and dirty solution, if seeing this error message irritates you.

Take a look at the error message, where the whining file is referenced,

Go to initializer under module Compatibility.

module Compatibility
  def initialize(app, options = {})
    options[:key] ||= '_session_id'
    # add secret if not supplied by options.
    options[:secret] ||= SecureRandom.hex(16)
    super
  end
  ...

edit:
This is also what @spastorino suggests in cb3181e.

@tehgeekmeister

I'm in support of @athlite's suggestion, myself. It's close to the PR I had originally submitted, though I think a little cleaner.

@guilleiguaran
Member

@athlite @mjtko talked yesterday with @spastorino. the quick workaround is only for 3.1.x and 3.2.x, in master we shouldn't use it.

@mjtko
mjtko commented Jan 8, 2013

@guilleiguaran Indeed! Hence my reversion of that commit and an alternative solution posed in my branch. 😄

@tehgeekmeister

Alright, I'm 👍 for @mjtko's approach, then. The approach I was working on is much uglier in comparison.

@mjtko
mjtko commented Jan 8, 2013

Right, I'm going to raise my branch as a PR for further discussion.

@guilleiguaran
Member

@mjtko open PR please :)

@mjtko
mjtko commented Jan 8, 2013

As above, PR now open as #8824. 😁

@guilleiguaran
Member

Fixed with the PR

@ndbroadbent

Will this fix also be released for 3.2.x, or should we use gem 'rack', '1.4.1' to get rid of the warning?

@guilleiguaran
Member

@ndbroadbent the warning should disappear in the next maintenance release of 3.2.x

@sozgul
sozgul commented Feb 26, 2013

I am having some issues with Rack, just bounced through 3-4 issues and landed here but god its so fucking hard to actually understand all the content here I am grateful more capable people are working on it. Since I cant really contribute much understanding myself I decided to thank you guys instead.

thank you

@spastorino
Member

@sozgul thanks for your words. I'm interested in knowing what issues are you having so we can help you

@steveklabnik
Member

@sozgul agreed, what @spastorino said. Please open a new issue and we can help you with your problem directly.

@sozgul
sozgul commented Feb 26, 2013

@spastorino, @steveklabnik, I really appreciate how fast you guys are to offer help. Just to clear the air, turns out I was the problem, Rack was having a problem with me not the other way around. My profile would make it obvious that I am not half as seasoned as a developer compared to you guy, but since you guys are so helpful I will contact you if I run into a real problem about rails. I do not have that much of a web presence yet, that will hopefully change in the future, if you guys also think I can help you with anything, please reach out.

@steveklabnik
Member

Great. :)

@mhenrixon

I am still having this incredibly annoying message that are destroying my spec output. I am on rails 3.2.13 and I thought this should have been back ported am I wrong? I can't use rack 1.4.1 since rails requires 1.4.5. Suggestions?

@drnic
drnic commented May 15, 2013

Also getting this issue with latest 3.2.12 rails

@spastorino
Member

@drnic really? I thought it was fixed. Same happens in 3.2.13? @guilleiguaran do you remember when was this exactly fixed?

@drnic
drnic commented May 16, 2013

@spastorino I'm seeing this:

=> Booting Puma
=> Rails 3.2.13 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Using github credentials for localhost
        SECURITY WARNING: No secret option provided to Rack::Session::Cookie.
        This poses a security threat. It is strongly recommended that you
        provide a secret to prevent exploits that may be possible from crafted
        cookies. This will not be supported in future versions of Rack, and
        future versions will even invalidate your existing user cookies.

        Called from: /Users/drnic/.rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_dispatch/middleware/stack.rb:43:in `new'.
@mjtko
mjtko commented May 16, 2013

@spastorino - I seem to recall that you fixed the warning for 3.2.13 with this commit: d9a0480

@spastorino
Member

@drnic what middlewares are you using?

@marktriggs marktriggs added a commit to archivesspace/archivesspace that referenced this issue Nov 26, 2013
@marktriggs marktriggs Suppress the (harmless) warning message about cookie secrets.
An issue between our current version of Rails and Rack:

  rails/rails#7372
740c8ef
@nanoseconds

same problem here

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