Avoid session fixation attacks.

This commit is contained in:
José Valim
2010-11-20 23:51:09 +01:00
parent 4310ad798c
commit fb1e9bc8a7
5 changed files with 40 additions and 3 deletions

View File

@@ -45,7 +45,7 @@ begin
s.authors = ['José Valim', 'Carlos Antônio']
s.files = FileList["[A-Z]*", "{app,config,lib}/**/*"]
s.extra_rdoc_files = FileList["[A-Z]*"] - %w(Gemfile Rakefile)
s.add_dependency("warden", "~> 0.10.7")
s.add_dependency("warden", "~> 1.0.2")
s.add_dependency("bcrypt-ruby", "~> 2.1.2")
end

View File

@@ -265,6 +265,11 @@ module Devise
@@warden_config_block = block
end
# Returns true if Rails version is bigger than 3.0.x
def self.rack_session?
Rails::VERSION::STRING[0,3] != "3.0"
end
# A method used internally to setup warden manager from the Rails initialize
# block.
def self.configure_warden! #:nodoc:

View File

@@ -83,7 +83,7 @@ module Devise
#
def stored_location_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
session.delete(:"#{scope}_return_to")
session.delete("#{scope}_return_to")
end
# The default url to be used after signing in. This is used by all Devise
@@ -114,7 +114,7 @@ module Devise
#
def after_sign_in_path_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
home_path = :"#{scope}_root_path"
home_path = "#{scope}_root_path"
respond_to?(home_path, true) ? send(home_path) : root_path
end

View File

@@ -36,4 +36,25 @@ class Warden::SessionSerializer
raise
end
end
end
unless Devise.rack_session?
class ActionDispatch::Request
def reset_session
session.destroy if session && session.respond_to?(:destroy)
self.session = {}
@env['action_dispatch.request.flash_hash'] = nil
end
end
Warden::Manager.after_set_user :event => [:set_user, :authentication] do |record, warden, options|
if options[:scope] && warden.authenticated?(options[:scope])
request, flash = warden.request, warden.env['action_dispatch.request.flash_hash']
backup = request.session.to_hash
backup.delete("session_id")
request.reset_session
warden.env['action_dispatch.request.flash_hash'] = flash
request.session.update(backup)
end
end
end

View File

@@ -236,6 +236,17 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
get '/users'
assert_equal "Cart", @controller.user_session[:cart]
end
test 'session id is changed on sign in' do
get '/users'
session_id = request.session["session_id"]
get '/users'
assert_equal session_id, request.session["session_id"]
sign_in_as_user
assert_not_equal session_id, request.session["session_id"]
end
end
class AuthenticationWithScopesTest < ActionController::IntegrationTest