4

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?

jtolds
  • 3,341
  • 3
  • 17
  • 14
  • Note that I am using non-transactional tests because the user I am creating in the test didn't seem to be visible to the login controller otherwise. – jtolds Jan 21 '11 at 21:47
  • Did you ever solve this? I'm having a similar issue in 3.0.7 / ruby-1.9.2. In my logout action I call `reset_session` and `cookies.delete(REMEMBER_ME_COOKIE_NAME)`. My session is not correctly destroyed unless I take out the cookie-deletion line. It's driving me insane. I assume the session store has a separate reference to the cookies and the controller is sending stale data back to the browser (which contains the old session ID). – d11wtq May 02 '11 at 05:30

1 Answers1

0

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)
jtolds
  • 3,341
  • 3
  • 17
  • 14