Thanks for Ryan Bates for his recent screencast on the Dangers of Session Hijacking. In short, a session can be hijacked if your user has an https session but then browses to the same site using http. An attacker can capture the cookie with a network sniffer and use it to access the user’s secure session.
If you’re using warden, you can use the serialization hooks to implement Ryan’s strategy.
Warden::Manager.serialize_into_session do |resource|
if request.ssl?
# Use an extra token under SSL to block session hijacking
# Based on http://railscasts.com/episodes/356-dangers-of-session-hijacking
session[:secure_token] = SecureRandom.hex
cookies.signed[:secure_token] = {secure: true, value: session[:secure_token]}
end
[resource.class.name, resource.id]
end
Warden::Manager.serialize_from_session do |identifier|
result = nil
begin
if !request.ssl? || cookies.signed[:secure_token] == session[:secure_token]
class_name, id = identifier
id = id.to_i rescue nil
klass = Kernel.const_get class_name
result = klass.find(id) if id.is_a? Integer
end
rescue ActiveRecord::RecordNotFound => exc
# Fail silently, stale cookie or user id
end
result
end

February 20th, 2013 7:39 pm
Doug,
This is a nice implementation, thanks a lot!
Do you think it’s really necessary to store the secure “session check” value as a signed cookie? Since it’s just a random check value to begin with, it seems unnecessary to sign/encrypt it. My understanding of the purpose of signed cookies is to prevent the end user from changing the value (i.e. if you wanted to store the user id in a cookie), but since changing the “session check” value at all will render the user session invalid (thanks to the strategy in this post) it should not be necessary to encrypt it.
Best,
-James
March 23rd, 2013 9:54 am
If the cookie is unsigned, and user makes non-SSL request after having authenticated, the cookie would be transmitted in the clear and could be intercepted.