In this post I’m going to demonstrate how to generate a safe token for a custom session module.
The Session Token
When a user logs into a website, there needs to be a way to keep track of who the person is after the authentication occurs. One method is to give the user a token after they log in and carry it around in a hidden field. Another method used by Microsoft is to embed the token in the URL itself. The token can also be placed in the authenticate field of the header. Last, and most common the token can be stored in a local cookie that is non-persistent (in other words it goes away when the browser closes, unless you’re using Chrome). For this blog post, it doesn’t really matter where the token is stored and used, I’m going to discuss the security of the token itself.
The first requirement is that you need to issue a unique token every time someone logs in and maintain a relationship between the user and the token (most likely in your database). There was a security breach a few years ago involving a secure website that use the account number as their token (I can’t remember the company off the top of my head). They also used it in the URL, which means that anybody looking over your shoulder can get your account number. In addition to this problem, I’m betting that their account numbers were sequentially issued. So a user could potentially log in, then modify the number in the URL and navigate around someone else’s account. Probably one of the worse implementations I’ve ever encountered.
So we need a unique key and the first thing that comes to mind is the GUID. Sounds good. In C# we can get a new GUID quickly. We can strip out the dashes if we like and just treat it as a string. One limitation to the GUID is that they are not unique if you take a subset of the GUID. In other words, you’ll need the whole thing. There is, however, another problem: The GUID sequence is predictable. The GUID is also hex, not really a string of characters, so the permutations is much smaller than it appears.
While I was reading about GUIDs, I came across this article at stack overflow:
Generating random string using RNGCryptoServiceProvider
This particular algorithm uses the RNGCryptoServiceProvider() to get a encrypted random number. The algorithm cited is supposed to generate 40 character random strings that are very distant from each other. So the test I want to perform uses the Levenshtein distance algorithm between each random generated string.
When I run 50,000 random strings comparing a string with it’s previous string I get a minimum difference in letters of 34, and an average of 39. That means that at least 34 of the 40 letters were different as a minimum and on average at least 39 letters will be different.
Where to Get the Code
You can download the sample code from my GitHub account here and modify the parameters.