views:

1898

answers:

3

I'm doing a first pass at rolling my own authentication and sessions in rails and am not sure that I understand the session support that is present. (By first pass, I mean I'm initially authenticating via http, not https. Production code will use https.)

My understanding of secure sessions is that you pass a token to the browser via a cookie over SSL, and then compare that token with the token stored on the server to see if it's really the user you think it is. I was hoping you guys could check my understanding of secure sessions, which is as follows:

  1. User gets login page and submits login name and password (POST via SSL).
  2. Server checks protocol and then checks sha1 of password (+ salt, usually) against existing hash in db. If they match, generate a session id, put it both in a(n SSL) cookie with the user id and in a server-side session store. Redirect user to the secured area of the site.
  3. That session id remains the same throughout the user's logged in session --or-- the server issues a new session id after each secure operation, sending it via an SSL cookie and storing the new value in the db.
  4. Any actions that involve private or secure data checks the session store for the existence of a session id for this user and, if present, compares the cookie's session_id against the session store before performing the action. If we're rotating session ids, issue a new session id (SSL cookie and server-side store) after the action.
  5. User logs out, which tells the server to remove the session id from the session store and clear the cookie. Or the cookie expires on the browser and/or on the server and re-authentication is required.

Are there any glaring errors in the above? Also, it seems like Rails' session[] support wouldn't prevent MITM attacks if the token in the cookie was merely a session id. Is that correct?

+5  A: 

I would suggest having a look at restful_authentication. This is the defacto standard auth library for Rails.

You don't actually need to generate the session_id yourself ... Rails handles all of this for you - checking the session id against the value provided by the browser. You can actually just store the user id in Rails session collection and then check that this exists.

You would technically be vulnerable to MITM attack if you do not use an SSL connection.

Toby Hede
+1  A: 

Try this web site, http://www.quarkruby.com/2007/10/21/sessions-and-cookies-in-ruby-on-rails. It appears to have a pretty comprehensive coverage of the subject.

One suggestion that I would have would be to not only use SSL but also encrypt and encode (Base 64) the session and other cookies that you send. Include a nonce (random value) with the session id so that the encrypted/encoded version changes every time you send it. If you are genuinely concerned about the session being hijacked you could also regenerate the session id periodically to limit the exposure of a hijacked cookie, although encrypting it should protected you if the cookies aren't persistent.

You should be able to use the encryption/encoding idea even if you use query parameters for the session id instead of cookies.

tvanfosson
+2  A: 
August Lilleaas