diff options
author | raggi <jftucker@gmail.com> | 2010-10-03 17:32:02 -0300 |
---|---|---|
committer | raggi <jftucker@gmail.com> | 2010-10-03 17:40:02 -0300 |
commit | f69bd1a7fe76d51f324d0299fdb4b4c906602d2e (patch) | |
tree | 7cc9f008eeeb9ddcb11a7416aa309801295ab3ac | |
parent | d3893c2709a9831f665245cf5da44e0019bead4f (diff) | |
download | rack-f69bd1a7fe76d51f324d0299fdb4b4c906602d2e.tar.gz |
Adding support for securerandom, will be in use by default. n.b. hacky test
-rw-r--r-- | lib/rack/session/abstract/id.rb | 19 | ||||
-rw-r--r-- | test/spec_session_abstract_id.rb | 43 |
2 files changed, 59 insertions, 3 deletions
diff --git a/lib/rack/session/abstract/id.rb b/lib/rack/session/abstract/id.rb index 6ff20fe3..1f85d616 100644 --- a/lib/rack/session/abstract/id.rb +++ b/lib/rack/session/abstract/id.rb @@ -4,6 +4,11 @@ require 'time' require 'rack/request' require 'rack/response' +begin + require 'securerandom' +rescue LoadError + # We just won't get securerandom +end module Rack @@ -164,7 +169,8 @@ module Rack :defer => false, :renew => false, :sidbits => 128, - :cookie_only => true + :cookie_only => true, + :secure_random => begin ::SecureRandom rescue false end } attr_reader :key, :default_options @@ -174,6 +180,9 @@ module Rack @default_options = self.class::DEFAULT_OPTIONS.merge(options) @key = options[:key] || "rack.session" @cookie_only = @default_options.delete(:cookie_only) + @sid_secure = @default_options[:secure_random] + @sid_template = "%0#{@default_options[:sidbits] / 4}x" + @sid_rand_width = (2**@default_options[:sidbits] - 1) end def call(env) @@ -193,8 +202,12 @@ module Rack # Monkey patch this to use custom methods for session id generation. def generate_sid - "%0#{@default_options[:sidbits] / 4}x" % - rand(2**@default_options[:sidbits] - 1) + r = if @sid_secure + SecureRandom.random_number(@sid_rand_width) + else + Kernel.rand(@sid_rand_width) + end + @sid_template % r end # Sets the lazy session at 'rack.session' and places options and session diff --git a/test/spec_session_abstract_id.rb b/test/spec_session_abstract_id.rb new file mode 100644 index 00000000..e1895243 --- /dev/null +++ b/test/spec_session_abstract_id.rb @@ -0,0 +1,43 @@ +### WARNING: there be hax in this file. + +require 'rack/session/abstract/id' + +describe Rack::Session::Abstract::ID do + id = Rack::Session::Abstract::ID + + def silence_warning + o, $VERBOSE = $VERBOSE, nil + yield + ensure + $VERBOSE = o + end + + def reload_id + $".delete $".find { |part| part =~ %r{session/abstract/id.rb} } + silence_warning { require 'rack/session/abstract/id' } + end + + should "use securerandom when available" do + begin + fake = false + silence_warning do + ::SecureRandom = fake = true unless defined?(SecureRandom) + end + reload_id + id::DEFAULT_OPTIONS[:secure_random].should.eql(fake || SecureRandom) + ensure + Object.send(:remove_const, :SecureRandom) if fake + end + end + + should "not use securerandom when unavailable" do + begin + sr = Object.send(:remove_const, :SecureRandom) if defined?(SecureRandom) + reload_id + id::DEFAULT_OPTIONS[:secure_random].should.eql false + ensure + ::SecureRandom = sr if defined?(sr) + end + end + +end
\ No newline at end of file |