Avoid session fixation attacks.

This commit is contained in:
José Valim 2010-11-20 23:18:41 +01:00
parent 6f205fe4c4
commit 71450998c5
5 changed files with 44 additions and 2 deletions

View File

@ -34,6 +34,11 @@
* Ensure namespaces has proper scoped views
* Ensure Devise does not set empty flash messages (by github.com/sxross)
== 1.1.4
* bugfix
* Avoid session fixation attacks
== 1.1.3
* bugfix

View File

@ -333,6 +333,11 @@ module Devise
end
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

@ -145,7 +145,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
@ -176,7 +176,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

@ -40,3 +40,24 @@ class Warden::SessionSerializer
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

@ -245,6 +245,17 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
ActiveSupport::Dependencies.autoload_paths.replace(paths)
end
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