The other day I was reading Jeff Prosise's article Foiling Session Hijacking Attempts and it got me to wondering how, exactly, session IDs are chosen and how they are guaranteed to be unique. The last thing you want to have happen is multiple, unique visitors hitting your site and being assigned, by chance, the exact same session ID, for such a case would cause these two unlucky visitors to “share” session state.
Session hijacking is an attack where the attacker attempts to guess a valid session ID or “steals“ a valid user's session cookie. Jeff says that guessing a valid session ID is a pretty hard attack to successfully pull off with ASP.NET since the session ID is “a highly-random 120-bit ID.” If you check out the formal docs for ASP.NET Session State - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconsessionstate.asp - it says:
"Each active ASP.NET session is identified and tracked using a 120-bit SessionID string containing only the ASCII characters that are allowed in URLs. SessionID values are generated using an algorithm that guarantees uniqueness so that sessions do not collide, and randomness so that a malicious user cannot use a new SessionID to calculate the SessionID of an existing session."
My question is - how are the selected session IDs guaranteed to be unique? In using Reflector & poking around the code for the session state (specifically System.Web.SessionState.SessionId and System.Web.SessionState.SessionStateModule), I fail to see how the algorithm guarantees uniqueness.
The only method that calls SessionId.Create is SessionStateModule.BeginAcquireState, which doesn't appear to do any validation to ensure the session ID is unique. Am I missing something obvious here?
From my understanding, the session ID is generated by a cryptographically strong algorithm, but I'm not too familiar with the properties of such algorithms. I imagine they provide a stronger pseudo-random technique than non-cryptographically strong algorithms... maybe one of the properties of such algorithms is that it takes a really long time before there's a random number picked that has been picked before.
And, yes, I realize that 2^120 is a huge number, a number that, if written out, would be comprised of 36 digits... but still, I am wondering how no conflict in session IDs is guaranteed.
So....... does anyone know how this guarantee is made? Am I missing finding something in Reflector or do I just need to have a better understanding of cryptographically strong pseudo-random number generators? Any info most appreciated.