5

I am using Ruby and Sinatra to develop an application.
I use

enable :sessions

in order to use the session variable provided by rack. How can I make all of the session cookies be HTTPOnly? Is it like this by default? I can't find any documentation on this.

Lev Dubinets
  • 788
  • 10
  • 32

1 Answers1

8

Instead of enable :sessions:

use Rack::Session::Cookie, {:httponly => true }

I'd suggest using the encrypted_cookie gem instead, it's far more secure. As an example, here's what I'll probably have for a project:

# app/main.rb
module Example
  class App < Sinatra::Base # this class in its own file
    # stuff here
  end
end

# app/config.rb
require "main"
module Example
  def self.app #
    Rack::Builder.app do
      cookie_settings = {        
        :key          => 'usr',
        :path         => "/",
        :expire_after => 86400,             # In seconds, 1 day.
        :secret       => ENV["COOKIE_KEY"], # load this into the environment of the server
        :httponly     => true
      }
      cookie_settings.merge!( :secure => true ) if ENV["RACK_ENV"] == "production"

      # AES encryption of cookies
      use Rack::Session::EncryptedCookie, cookie_settings

      # other stuff here

      run App
    end
  end
end

# config.ru
require "app/config"
run Example.app  # this in the rackup file

(To clarify why I've laid it out this way - this kind of stucture allows me to split the app up and use it easier in tests by just requiring the app/config.rb. YMMV)

ian
  • 12,003
  • 9
  • 51
  • 107
  • Very nice. My application's flow is a lot simpler. Can I just use that Rack::Builder.app statement in my config.ru file, instead of enable :sessions ? Also, I use a session secret by writing set :session_secret, ENV['SESSION_KEY'] || "development_secret". Can I do this the same way with the rack session cookie? – Lev Dubinets Sep 22 '12 at 22:23
  • Yes, don't use enable sessions as well as this, just the Builder. You can also do the `||` trick, but because the env vars tend to increase over time (as they're so useful) I put the rackup command in a rake task that has a prerequisite task that sets up all the env vars with development values. – ian Sep 23 '12 at 12:07
  • 1
    Does `Rack::Session::EncryptedCookie` really provide `:httponly` option? – Weihang Jian Dec 05 '16 at 20:57
  • @JianWeihang No it doesn't, thanks for pointing it out. I've corrected the post. – ian Dec 05 '16 at 21:44
  • @JianWeihang Okay, I was hasty. Encrypted Cookie doesn't, but it relies on Rack's session code which does implement HttpOnly. It's in their specs [here](https://github.com/rack/rack/blob/1.6.5/test/spec_response.rb#L82) for v1.65 and [here](https://github.com/rack/rack/blob/2.0.1/test/spec_response.rb#L100) for version v2.x. – ian Dec 05 '16 at 21:55
  • 1
    @iain Thank you, after digging the source code, I found Encrypted::Cookie uses `Rack::Utils.set_cookie_header!`. – Weihang Jian Dec 06 '16 at 07:28