Question

I'm writing an integration test to make sure my webapp isn't vulnerable to session fixation.

I have manually verified that reset_session is actually firing in the authentication logic, and further that the cookie does indeed change when I log in with my web browser (so, I'm not vulnerable to session fixation anymore), but I can't get my RSpec integration test to successfully verify this.

Here is my RSpec integration test.

require 'spec_helper'

describe "security" do

  self.use_transactional_fixtures = false

  append_after(:each) do
    ALL_MODELS.each &:delete_all
  end

  describe "session fixation" do
    it "should change the cookie session id after logging in" do

      u = test_user :active_user => true,
                    :username => "nobody@example.com",
                    :password => "asdfasdf"
      u.save!

      https!

      get_via_redirect "/login"
      assert_response :success
      cookie = response.header["Set-Cookie"].split(";").select{|x| x.match(/_session/)}[0].split("=")[1].strip

      post_via_redirect "/login", "user[email]" => "nobody@example.com",
                                  "user[password]" => "asdfasdf",
                                  "user[remember_me]" => "1"
      assert_response :success
      path.should eql("/dashboard")
      cookie.should_not eql(response.header["Set-Cookie"].split(";").select{|x| x.match(/_session/)}[0].split("=")[1].strip)
    end
  end
end

Everything works except for the very last assert. The cookie doesn't change.

Are there any known issues with RSpec/Rails integration tests where reset_session doesn't work as expected? What can I do to write a test that verifies session fixation is not an issue?

Was it helpful?

Solution

So I eventually did end up figuring this out.

I was trying to edit the response header directly to test cookies, but I guess that's not the blessed way.

In integration tests with Rails 2.x anyway, there's a cookies hash that you can use. Here's what the test ended up looking like:

  u = test_user :active_user => true,
                :username => "nobody@example.com",
                :password => "asdfasdf"
  u.save!

  https!

  get_via_redirect "/login"
  assert_response :success
  cookie = cookies['_session']
  cookie.should be_present
  path.should == "/login"

  post_via_redirect "/login", "user[email]" => "nobody@example.com",
                              "user[password]" => "asdfasdf",
                              "user[remember_me]" => "1"
  assert_response :success
  path.should eql("/?login_success=1")
  new_cookie = cookies['_session']
  new_cookie.should be_present
  cookie.should_not eql(new_cookie)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top