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

Ticket #10048 (closed defect: fixed)

Opened 3 years ago

Last modified 2 years ago

[PATCH] Session fixation (cookie_only) functionality is broken

Reported by: sameer Assigned to: technoweenie@gmail.com
Priority: normal Milestone: 2.0
Component: ActionPack Version: edge
Severity: normal Keywords: session fixation cookie_only
Cc:

Description

In cgi_process, the CgiRequest constructor accepts a session_options hash as a parameter. It then deletes the :cookie_only attribute from the hash, and stores the value in an instance variable @cookie_only:

from actionpack-1.13.5/lib/action_controller/cgi_process.rb, line 38

  class CgiRequest < AbstractRequest #:nodoc:
    attr_accessor :cgi, :session_options, :cookie_only
    class SessionFixationAttempt < StandardError; end #:nodoc:
    DEFAULT_SESSION_OPTIONS = {
      :database_manager => CGI::Session::PStore,
      :prefix           => "ruby_sess.",
      :session_path     => "/",
      :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

However, the implementation in the rails Dispatcher passes in the constant DEFAULT_SESSION_OPTIONS. So, the CgiRequest constructor is actually removing the :cookie_only attribute from DEFAULT_SESSION_OPTIONS. So, @cookie_only is set correctly the first time CgiRequest is instantiated, but every subsequent time, it's set to nil, which evaluates to false. So, the session fixation logic stops working after the first request:

from actionpack-1.13.5/lib/action_controller/cgi_process.rb, line 111

    def session
      <snip snip>
          stale_session_check! do
            if @cookie_only && request_parameters[session_options_with_string_keys['session_key']]
              raise SessionFixationAttempt
            end
      <snip snip>

The CgiRequest constructor shouldn't delete the :cookie_only attribute from the session_options hash, and it doesn't need to have a member variable @cookie_only. Instead, it could just look up the :cookie_only value from session_options_with_string_keys, which merges the DEFAULT_SESSION_OPTIONS and the passed in session_options (see attached diff).

With the proposed change, you'll be able to override the :cookie_only session option on a per action basis, like so:

class SomeController < ApplicationController

  session :cookie_only => false, :only => :do_something

  def do_something
    render :text => "something"
  end
end

Included in the attached diff is: * my proposed patch * updated unit tests that both highlight the problem and demonstrate the patch works

Attachments

cookie_only.diff (3.2 kB) - added by sameer on 11/01/07 07:08:45.
fix_broken_session_fixation_catching.patch (4.9 kB) - added by theflow on 11/11/07 20:53:15.

Change History

11/01/07 07:08:45 changed by sameer

  • attachment cookie_only.diff added.

11/11/07 20:52:25 changed by theflow

  • component changed from ActiveRecord to ActionPack.
  • milestone changed from 1.2.6 to 2.0.

+1

While trying to write tests for #9930 I also discovered this. Not only is this broken on subsequent requests, it's also complety broken on edge because of the refactoring done in [6764].

I've attached a patch that fixes catching session fixation attempts on edge, fixes the problem here and fixes #9930.

11/11/07 20:53:15 changed by theflow

  • attachment fix_broken_session_fixation_catching.patch added.

11/18/07 22:02:47 changed by david

  • owner changed from core to technoweenie@gmail.com.

11/21/07 04:29:02 changed by nzkoz

(In [8176]) Refactor cookie_only option to survive multiple requests and add regression tests. References #10048. [theflow]

11/21/07 05:00:29 changed by nzkoz

  • status changed from new to closed.
  • resolution set to fixed.

(In [8177]) Merge [8176] to stable to fix session fixation attacks. Closes #10048 [theflow, Koz]

11/21/07 05:02:37 changed by nzkoz

Guys,

Thanks for the fixes, really appreciated

But that functionality was introduced for security reasons, in future do not use trac to report potential security issues. The instructions are available on the new ticket page or http://rubyonrails.org/security-policy.

All the best