Most secure way to generate a random session ID for a cookie?

13,671

Solution 1

If the only information in the cookie is an identifier, essentially a label, the only attack you're trying to protect from is an attacker guessing what it is. So use some random bytes. Enough random bytes that it's "unguessable."

Then squish the random bytes into something that fits within the confines of which characters you can use in a HTTP cookie. base64 works for this. It's not absolutely optimal, because there are more than 64 cookie-safe characters and it tends to leave trailing == characters which add bytes to the header but not randomness, but that's fine. It works and Python can probably do the base64 encoding faster than anything else we can come up with.

If you also want to prepend the user ID to it, that will make things easier to trace and debug, which will probably make your life easier, so go ahead. It doesn't give an attacker any significant advantage. (unless they manage to steal one without being able to otherwise determine what user they're stealing from, which seems unlikely.)

Solution 2

Go buy Bruce Schneier's Secrets and Lies and his Practical Cryptography. Go ahead and order Ross Anderson's Security Engineering 2nd Ed. while you're at it. Now, read Secrets and Lies -- trust me, it's a fun read. :) Then read Practical Cryptography. At that point you should have a better grounding in what you need to do when implementing software that needs some security. Go ahead and do your rough-draft implementation. Now that your copy of Security Engineering has arrived, read it... though that one you may want to digest a bit slower; it's a rather heavy tome.

There is also a whitepaper on web authentication dos and don'ts that is worth reading and a bit more directly applicable to what you're doing. I still recommend the books above.

And another timely article from LWN.net which lists a good number of pitfalls you need to work to avoid. (BTW, LWN.net is well worth subscribing to, and I highly recommend it. The above link allows free access to that article which otherwise would not be available to non-subscribers yet.)

Solution 3

You can use os.urandom:

os.urandom(n)

Return a string of n random bytes suitable for cryptographic use.

This function returns random bytes from an OS-specific randomness source. The returned data should be unpredictable enough for cryptographic applications, though its exact quality depends on the OS implementation. On a UNIX-like system this will query /dev/urandom, and on Windows it will use CryptGenRandom. If a randomness source is not found, NotImplementedError will be raised.

New in version 2.4.

Solution 4

If you're using Python 3.6+, you can use the new library secrets.

from secrets import token_urlsafe

token = token_urlsafe(64)   # something like Drmhze6EPcv0fN_81Bj-nA....
Share:
13,671
ensnare
Author by

ensnare

Updated on June 12, 2022

Comments

  • ensnare
    ensnare almost 2 years

    I'm writing my own sessions controller that issues a unique id to a user once logged in, and then verifies and authenticates that unique id at every page load. What is the most secure way to generate such an id? Should the unique id be completely random? Is there any downside to including the user id as part of the unique id?