diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2005-11-09 06:00:46 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2005-11-09 06:00:46 +0000 |
commit | bb4c32e2b5858b25524191ee4868e616fa5bd9be (patch) | |
tree | 510545bd430a8d8905e0b84cf8da0b25f38e35b2 | |
parent | 98ae24b9676fb4c28d25c13ace8d08ec741aad04 (diff) | |
download | rails-bb4c32e2b5858b25524191ee4868e616fa5bd9be.tar.gz rails-bb4c32e2b5858b25524191ee4868e616fa5bd9be.tar.bz2 rails-bb4c32e2b5858b25524191ee4868e616fa5bd9be.zip |
Delete existing sessions with the same session id before creating a new session. Prevents duplication and hijacking.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2946 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | actionpack/lib/action_controller/cgi_process.rb | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/actionpack/lib/action_controller/cgi_process.rb b/actionpack/lib/action_controller/cgi_process.rb index 7f05e21cb8..62bbd02e32 100644 --- a/actionpack/lib/action_controller/cgi_process.rb +++ b/actionpack/lib/action_controller/cgi_process.rb @@ -89,37 +89,26 @@ module ActionController #:nodoc: def port_from_http_host $1.to_i if env['HTTP_HOST'] && /:(\d+)$/ =~ env['HTTP_HOST'] end - - def session - return @session unless @session.nil? - begin - @session = (@session_options == false ? {} : CGI::Session.new(@cgi, session_options_with_string_keys)) - @session["__valid_session"] - return @session - rescue ArgumentError => e - if e.message =~ %r{undefined class/module (\w+)} - begin - Module.const_missing($1) - rescue LoadError, NameError => e - raise( - ActionController::SessionRestoreError, - "Session contained objects where the class definition wasn't available. " + - "Remember to require classes for all objects kept in the session. " + - "(Original exception: #{e.message} [#{e.class}])" - ) - end - - retry + def session + unless @session + if @session_options == false + @session = Hash.new else - raise + if session_options_with_string_keys['new_session'] == true + @session = new_session + else + @session = CGI::Session.new(@cgi, session_options_with_string_keys) + end + stale_session_check! end end + @session end - + def reset_session @session.delete if CGI::Session === @session - @session = (@session_options == false ? {} : new_session) + @session = new_session end def method_missing(method_id, *arguments) @@ -127,12 +116,38 @@ module ActionController #:nodoc: end private + # Delete an old session if it exists then create a new one. def new_session - CGI::Session.new(@cgi, session_options_with_string_keys.update("new_session" => true)) + if @session_options == false + Hash.new + else + CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => false)).delete rescue nil + CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => true)) + end end - + + def stale_session_check! + @session['__valid_session'] + rescue ArgumentError => argument_error + if argument_error.message =~ %r{undefined class/module (\w+)} + begin + Module.const_missing($1) + rescue LoadError, NameError => const_error + raise ActionController::SessionRestoreError, <<end_msg +Session contains objects whose class definition isn't available. +Remember to require the classes for all objects kept in the session. +(Original exception: #{const_error.message} [#{const_error.class}]) +end_msg + end + + retry + else + raise + end + end + def session_options_with_string_keys - DEFAULT_SESSION_OPTIONS.merge(@session_options).inject({}) { |options, (k,v)| options[k.to_s] = v; options } + @session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).inject({}) { |options, (k,v)| options[k.to_s] = v; options } end end |