Rails/RSpec: reset_session not changing Set-Cookie HTTP header value during integration tests
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?
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)
精彩评论