diff --git a/README.md b/README.md index b1c1a64..c1f08a7 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,13 @@ HTTP cookie-based sessions. `session_expire` -> The number of seconds from now the cookie will be valid `session_secret` -> A secret key that is used to check the integrity of session data + `session_encrypted` -> Set to `true` to use Rack::Session::EncryptedCookie. + Note that `session_secret` must also be a (random) + string > 32 chars. See below. + +***Rack::Session::EncryptedCookie** is implemented through the `encrypted_cookie` gem, which provides 256-bit-AES-encrypted, tamper-proof cookies for Rack. Your `:session_secret` must be at least 32 bytes long and should be really random. Don't use a password or passphrase, generate something random. E.g. run this in a terminal and paste the output into your script: + + $ ruby -rsecurerandom -e "puts SecureRandom.hex(32)" ## Helper Methods @@ -47,7 +54,8 @@ require 'sinatra' require 'sinatra/session' set :session_fail, '/login' -set :session_secret, 'So0perSeKr3t!' +set :session_secret, 'So0perSeKr3t!So0perSeKr3t!So0perSeKr3t!' +set :session_encrypted, true get '/' do session! diff --git a/lib/sinatra/session.rb b/lib/sinatra/session.rb index 89c7beb..e0282a0 100644 --- a/lib/sinatra/session.rb +++ b/lib/sinatra/session.rb @@ -1,4 +1,5 @@ require 'sinatra/base' +require 'encrypted_cookie' module Sinatra module Session @@ -38,8 +39,20 @@ def session! # of being provided up front. module Cookie def self.new(app, options={}) - options.merge!(yield) if block_given? - Rack::Session::Cookie.new(app, options) + # If true, use EncryptedCookie. The :session_secret also needs to be a + # (random) string > 32 chars. + if (app.settings.session_encrypted && app.settings.session_secret.length >= 32) + Rack::Session::EncryptedCookie.new(app, { + :key => app.settings.session_name, + :path => app.settings.session_path, + :domain => app.settings.session_domain, + :expire_after => app.settings.session_expire, + :secret => app.settings.session_secret + }) + else + options.merge!(yield) if block_given? + Rack::Session::Cookie.new(app, options) + end end end @@ -50,6 +63,9 @@ def self.registered(app) # the session is not valid. app.set :session_fail, '/login' + # Set to true to use EncryptedCookie. + app.set :session_encrypted, false + # Parameters for the session cookie. app.set :session_name, 'sinatra.session' app.set :session_path, '/' diff --git a/sinatra-session.gemspec b/sinatra-session.gemspec index d46c2bb..66fa0ba 100644 --- a/sinatra-session.gemspec +++ b/sinatra-session.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'sinatra-session' - s.version = '1.0.1' + s.version = '1.1.0' s.date = Time.now.strftime('%Y-%m-%d') s.summary = 'Simple, secure sessions for Sinatra' @@ -15,6 +15,7 @@ Gem::Specification.new do |s| %w< sinatra-session.gemspec Rakefile README.md > s.add_dependency('sinatra', '>= 1.0') + s.add_dependency('encrypted_cookie', '>= 0.0.4') s.add_development_dependency('rake') s.rdoc_options = %w< --line-numbers --inline-source --title Sinatra::Session --main Sinatra::Session >