How to secure a Rails app against Firesheep?
Asked Answered
D

2

20

I have not been able to find an easy guide for securing a Ruby on Rails app against a Firesheep.

In case you don't know, Firesheep jacks session cookies if your app doesn't force SSL and set the secure flag in the cookie. I had to do some searching to find these two things, so I thought I'd post what I found here and see if there is anything else I'm missing.

Step 1 Force SSL

There are two ways to do this that I found. One is using the ssl_requirement plugin, but this is a pain because you have to specifically specify ssl_required :action1, :action2 in every controller.

The preferable way appears to be by using Rack Middleware, via this post: Force SSL using ssl_requirement in Rails 2 app. Works like a charm.

Step 2 Make cookies secure

For this I followed these directions, which tell you to put the following in your config/environment/production.rb file:

config.action_controller.session = {
    :key     => 'name_of_session_goes_here',
    :secret          => 'you need to fill in a fairly long secret here and obviously do not copy paste this one',
    :expire_after    => 14 * 24 * 3600, #I keep folks logged in for two weeks
    :secure => true #The session will now not be sent or received on HTTP requests.
  }

This was all pretty straight-forward on my Rails 2.x app. Did I miss anything? Is it different for Rails 3?

Drawn answered 10/11, 2010 at 17:47 Comment(0)
H
17

Looks pretty good to me. It's pretty similar in Rails 3, though by default the session config is stored in config/initializers/session_store.rb. I usually tweak mine to look something like...

MyApp::Application.config.session_store :cookie_store, :key => '_my_app_session',
                                                       :secure => Rails.env == 'production', # Only send cookie over SSL when in production mode
                                                       :httponly => true, # Don't allow Javascript to access the cookie (mitigates cookie-based XSS exploits)
                                                       :expire_after => 60.minutes

And the secret is held in config/initializers/secret_token.rb:

MyApp::Application.config.secret_token = 'secret secrets are no fun...'

If you have access to your Apache (or whatever) config, you can also force SSL usage at that level. Strikes me as a more appropriate place to do that, but I guess not everyone has that option.

Hummock answered 10/11, 2010 at 20:16 Comment(5)
Thanks for the reply. I'm deploying to Heroku so middleware seemed the best place to force SSL.Drawn
Note that the option to make the cookie inaccessible to JavaScript is :httponly rather than :http_only. The latter was deprecated in Rails 2.3 (or earlier) and removed in Rails 3. I believe these changes are to bring Rails in line with Rack.Calyptrogen
Nice answer, but using HTTP in testing and HTTPSs in production makes it easy to miss mixed-content problems and other subtle bugs.Bloodcurdling
I find this more readable: :secure => Rails.env.production?, in my case it's actually :secure => (Rails.env.staging? || Rails.env.production?), or it could also be :secure => !(Rails.env.test? || Rails.env.development?)... secure by defaultTenaculum
secrets secrets hurt someoneHaemachrome
F
1

Seeing as this SO post ranks pretty high in Google I thought I'd share the approach I used for securing an app.

If you want to ensure SSL and also ensure secure cookies then you could use a Rack middleware:

https://github.com/tobmatth/rack-ssl-enforcer

I evaluated lots of different options and configuration settings for doing this but the rack middleware felt like the best option with the least amount of config - very easy to deploy. It has some great config options to filter specific rules, hosts, paths etc.

I tested that it does indeed set secure cookies correctly and it does. The one thing I noted was it only did it when logging out and logging in again - but that was using Devise.

Football answered 1/2, 2014 at 22:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.