From eb5033ad6b4a12a32e1493fb5b9aeee9eb75f10e Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Tue, 2 Oct 2007 05:58:16 +0000 Subject: Merge session fixation fixes from stable git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7722 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/lib/action_controller/cgi_process.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'actionpack/lib/action_controller') diff --git a/actionpack/lib/action_controller/cgi_process.rb b/actionpack/lib/action_controller/cgi_process.rb index f3282922e6..cfa6f6dc54 100644 --- a/actionpack/lib/action_controller/cgi_process.rb +++ b/actionpack/lib/action_controller/cgi_process.rb @@ -10,8 +10,8 @@ module ActionController #:nodoc: # (default). Additionally, there is CGI::Session::DRbStore and CGI::Session::ActiveRecordStore. Read more about these in # lib/action_controller/session. # * :session_key - the parameter name used for the session id. Defaults to '_session_id'. - # * :session_id - the session id to use. If not provided, then it is retrieved from the +session_key+ parameter - # of the request, or automatically generated for a new session. + # * :session_id - the session id to use. If not provided, then it is retrieved from the +session_key+ cookie, or + # automatically generated for a new session. # * :new_session - if true, force creation of a new session. If not set, a new session is only created if none currently # exists. If false, a new session is never created, and if none currently exists and the +session_id+ option is not set, # an ArgumentError is raised. @@ -21,6 +21,8 @@ module ActionController #:nodoc: # server. # * :session_secure - if +true+, this session will only work over HTTPS. # * :session_path - the path for which this session applies. Defaults to the directory of the CGI script. + # * :cookie_only - if +true+ (the default), session IDs will only be accepted from cookies and not from + # the query string or POST parameters. This protects against session fixation attacks. def self.process_cgi(cgi = CGI.new, session_options = {}) new.process_cgi(cgi, session_options) end @@ -31,18 +33,21 @@ module ActionController #:nodoc: end class CgiRequest < AbstractRequest #:nodoc: - attr_accessor :cgi, :session_options + attr_accessor :cgi, :session_options, :cookie_only + class SessionFixationAttempt < StandardError; end #:nodoc: DEFAULT_SESSION_OPTIONS = { :database_manager => CGI::Session::CookieStore, # store data in cookie :prefix => "ruby_sess.", # prefix session file names - :session_path => "/" # available to all paths in app + :session_path => "/", # available to all paths in app + :cookie_only => true } unless const_defined?(:DEFAULT_SESSION_OPTIONS) def initialize(cgi, session_options = {}) @cgi = cgi @session_options = session_options @env = @cgi.send!(:env_table) + @cookie_only = session_options.delete :cookie_only super() end @@ -109,6 +114,9 @@ module ActionController #:nodoc: @session = Hash.new else stale_session_check! do + if @cookie_only && request_parameters[session_options_with_string_keys['session_key']] + raise SessionFixationAttempt + end case value = session_options_with_string_keys['new_session'] when true @session = new_session -- cgit v1.2.3