How to secure a Rails app against Firesheep?
ruby-on-rails, security
Solution
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.
Problem
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?