Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 2946

Show
Ignore:
Timestamp:
11/09/05 06:00:46 (3 years ago)
Author:
bitsweat
Message:

Delete existing sessions with the same session id before creating a new session. Prevents duplication and hijacking.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/lib/action_controller/cgi_process.rb

    r2596 r2946  
    9090      $1.to_i if env['HTTP_HOST'] && /:(\d+)$/ =~ env['HTTP_HOST'] 
    9191    end 
    92      
     92 
    9393    def session 
    94       return @session unless @session.nil? 
    95  
    96       begin 
    97         @session = (@session_options == false ? {} : CGI::Session.new(@cgi, session_options_with_string_keys)) 
    98         @session["__valid_session"] 
    99         return @session 
    100       rescue ArgumentError => e 
    101         if e.message =~ %r{undefined class/module (\w+)} 
    102           begin 
    103             Module.const_missing($1) 
    104           rescue LoadError, NameError => e 
    105             raise( 
    106               ActionController::SessionRestoreError,  
    107               "Session contained objects where the class definition wasn't available. " + 
    108               "Remember to require classes for all objects kept in the session. " + 
    109               "(Original exception: #{e.message} [#{e.class}])" 
    110             ) 
     94      unless @session 
     95        if @session_options == false 
     96          @session = Hash.new 
     97        else 
     98          if session_options_with_string_keys['new_session'] == true 
     99            @session = new_session 
     100          else 
     101            @session = CGI::Session.new(@cgi, session_options_with_string_keys) 
    111102          end 
    112          
    113           retry 
    114         else 
    115           raise 
     103          stale_session_check! 
    116104        end 
    117105      end 
     106      @session 
    118107    end 
    119      
     108 
    120109    def reset_session 
    121110      @session.delete if CGI::Session === @session 
    122       @session = (@session_options == false ? {} : new_session) 
     111      @session = new_session 
    123112    end 
    124113 
     
    128117 
    129118    private 
     119      # Delete an old session if it exists then create a new one. 
    130120      def new_session 
    131         CGI::Session.new(@cgi, session_options_with_string_keys.update("new_session" => true)) 
     121        if @session_options == false 
     122          Hash.new 
     123        else 
     124          CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => false)).delete rescue nil 
     125          CGI::Session.new(@cgi, session_options_with_string_keys.merge("new_session" => true)) 
     126        end 
    132127      end 
    133        
     128 
     129      def stale_session_check! 
     130        @session['__valid_session'] 
     131      rescue ArgumentError => argument_error 
     132        if argument_error.message =~ %r{undefined class/module (\w+)} 
     133          begin 
     134            Module.const_missing($1) 
     135          rescue LoadError, NameError => const_error 
     136            raise ActionController::SessionRestoreError, <<end_msg 
     137Session contains objects whose class definition isn't available. 
     138Remember to require the classes for all objects kept in the session. 
     139(Original exception: #{const_error.message} [#{const_error.class}]) 
     140end_msg 
     141          end 
     142 
     143          retry 
     144        else 
     145          raise 
     146        end 
     147      end 
     148 
    134149      def session_options_with_string_keys 
    135         DEFAULT_SESSION_OPTIONS.merge(@session_options).inject({}) { |options, (k,v)| options[k.to_s] = v; options } 
     150        @session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).inject({}) { |options, (k,v)| options[k.to_s] = v; options } 
    136151      end 
    137152  end