Jun 11 2012

Prevent Rails Session Hijacking in Warden

Category: UncategorizedDoug Puchalski @ 12:47 pm

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

2 Responses to “Prevent Rails Session Hijacking in Warden”

  1. James S says:

    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

  2. Doug Puchalski says:

    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.

Leave a Reply