UPDATE
We eventually had a meeting with some programmers on the Acunetix team and they realized there may be a few bugs in their code that are causing this to be displayed in the scan as more of an issue than it actually may be. The general consensus was to ignore the scan results and use the out-of-the-box ASP.NET Session ID generation as it should be secure enough for our site.
@Vasile Bujac since your answer was the only one and mentioned using the ASP.NET standard solution I took that as the answer, but thanks everyone for your help.
We use Acunetix's Retina scanner at work to do security scans on our applications. It's telling us that our session ID's are not random enough and too predictable. I'm not exactly sure how ASP.NET generates the session ID by default (I thought it was GUID anyways?), but I went ahead and implemented the method of extending the SessionIDManager class and overriding the CreateSessionID and Validate methods to use a Guid as explained in this MSDN article.
While this makes it slightly more random, it is still not producing the "desired" effect according to Acunetix. I even added the regenerateExpiredSessionId="true"
property to the web.config and that had no effect. I have a feeling that I may need to deliberately call Session.Abandon()
to truly clear the session and get a new ID. Problem is then I have to call it right before a user logs in since it's the only fail-proof way to know the user is starting a new session. So I couldn't set anything in session until the next page is loaded with the way the Abandon
method works, and that would mean an in-between page which isn't very ideal but would do the trick.
Has anyone ever experienced this or successfully implemented a fix?
Also, just an FYI, we don't use membership/forms authentication, we just create a new custom user class when someone logs in and save that in session for later use.
Report from Acunetix:
Description: Session tokens that exhibit low entropy ("randomness") are often susceptible to prediction attacks. Insecure tokens can be due to inadequate pseudo-random number generator, time-based values, static values, or values based on user attributes (username or user ID). This means that an attacker would be able to guess a valid session token after monitoring the application for a short period of time and gathering the session tokens it creates. If the attacker determines a valid session token for another user, then it may be possible to view, modify, or delete arbitrary users' data without having to guess the victim's username or password. Consequently, the ability to deduce valid session tokens enables the attacker to bypass login pages and obviate the need to brute force accounts. Additionally, static tokens can enable the attacker to target users even if the victim is not currently logged into the application. This increases the pool of victims which the attacker can target.
Session tokens should be created with a strong random number generator and gathered from a large pool of numbers. For example, an operating system's rand() function can usually be sufficient if it can produce 32-bit values that are a statistically uniform distribution. Poor session tokens are incremental, rely on the user's account ID, only use time stamps, or have other highly deterministic information. Other methods of protecting a session token's security are to always transmit them over SSL, automatically expire the token after a certain period of time, and explicitly expiring the token whenever a user logs out of the application.
Recommendations: If the session values exhibit strong randomness, but are chosen from a small pool of values, then the attacker has a better chance of simply guessing a valid token. A web application's session management can be improved by implementing several complementary techniques:
As I remember, ASP.NET session id generator gives good protection against session prediction. The session id has 24 characters using [a-z] chars and [0-5] digits (total of 32 possible chars which is 2^5) which gives a total of 2^(5*24) = 2^120 possible values. However you can implement a SessionIDManager to append some information (like user hostaddress, user-agent, a validation token using a HMAC algorithm) for even better protection - so that a session id comming from a different IP Address or different browser wouldn't pass the validation. If you have forms authentication implemented, this is not necessary since the authentication ticket already provides these kinds of protection.
If you want a better random session id you can use a RandomNumberGenerator such as RNGCryptoServiceProvider in your SessionIDManager and fill a bunch of bytes (say 32 which is 256 bits), then encode them using Base64
byte[] random = new byte[100];
//RNGCryptoServiceProvider is an implementation of a random number generator.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(random); // The array is now filled with cryptographically strong random bytes.
return Convert.ToBase64String(random)
However, this article says that the max length of your session id is 80, so you must override the Validate method also in order for it to work.