Friday, May 23, 2014

Tornado authentication best practice

Here is an extract of the Google group discussion
https://groups.google.com/forum/#!msg/python-tornado/ty8Xerv0ALc/IQRMM9n_4agJ
Response from Ben:
I think the author's argument against persistent login is misplaced; persistent login cookies are compatible with the security needs of most sites.  However, the points he make here are valid and are best practices be followed whether your login cookies are persistent or not.  (Tornado's example apps don't do this.  I'd like to do a better job of steering people towards best practices, but I also don't want to overwhelm the simple examples with complex login functionality).  

Specifically, you should store a random session key for each user in your database and include this session key in your signed cookies.  The session key would be deleted or reset to a new random value when the user explicitly logs out or changes their password, and cookies would be rejected if they didn't have the right session key.

Storing only a hash of the session key in the database is a good idea, although this means that you have to have a one-to-many relationship between users and session keys (unless you want a login on one browser to invalidate any current logins on other browsers), since you won't be able to reuse the previous session key the next time the user logs in.  The recommendation to use bcrypt or equivalent is kind of silly, though - a sufficiently large random session key cannot be brute forced even if the hash is a fast one, so just use your preferred SHA-family hash (bcrypt and friends are for when you're using low-entropy keys so that humans can remember them).  Also note that it's important to use a good cryptographic random number generator (e.g. os.urandom instead of anything from the python stdlib's random module).  

Server-side session keys ensure that even if a cookie is stolen (which can happen for non-persistent cookies too) it can be invalidated as soon as the user logs out, instead of being usable until it expires.  Hashing the session keys in the database means that even an attacker who has read-only access to your database and a copy of your cookie-signing key cannot forge login cookies for arbitrary users.  

-Ben

No comments:

Post a Comment