Session ID not random enough - ASP.NET
Asked Answered
C

1

10

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:

CWE-330 CAPEC-59 OWASP2007-A7

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:

  • Make sure that the Token values are at least 32 bits in size, especially for applications with large numbers of concurrent users and high amounts of daily page requests.
  • The bit size of the source of the entropy (random values) is more important than the bit size of the actual session token. For example, an MD5 hash produces a 128 bit value. However, the MD5 hash of incremental values, a timestamp, or 8-bit random numbers are each insecure because the source of the random values can be easily predicted. Consequently, the 128 bit size does not represent an accurate measure of the session token. The minimum size of the entropy source is 32 bits, although larger pools (48 or 64 bits) may be necessary for sites with over 10,000 concurrent users per hour.
  • In most cases, application-generated tokens (e.g. ASP.NET_SessionId, ASPSESSIONID, JSPSESSIONID, PHPSESSIONID) provide sufficiently large random values to prevent session prediction attacks. The application should use these session management alogorithms unless a custom session mechanism has been thoroughly reviewed and tested.
  • Track user attributes associated with the session token with server-side objects to prevent user impersonation attacks. If the application does not strictly associate a user's session token with that user's profile information, then an attacker may be able to view arbitrary information by manipulating client-side values. For example, if the application sets a strong session token, but performs SQL queries based on a "UserId" cookie, then an attacker only needs to modify the "UserId" cookie to impersonate someone else. The application would be more secure if it associated the "UserId" value with the server-side session object because the attacker would not be able to modify the value.
  • Expire session tokens when the user logs out of the application or after a predetermined period of inactivity. We recommend using a 20 minute timeout for a session token, although this largely depends on the type of application and the expected usage.
Cognition answered 1/8, 2011 at 18:17 Comment(4)
What aspect of the session ID do they think is a problem? You're not using it for authorization, are you ?Gelatin
I just added the report from acunetix to the post. Not using it for authorization. It has a problem with the randomness of the cookie value (the "ASP.NET_SessionId" cookie) for the session ID.Cognition
Have you tried lookin at your ASP.NET_SessionId cookie value using fiddler or firebug? The token generated as session id by ASP.NET is a lot greater than 32 bits recommended by your toolVichy
Session.Abandon() only works for INPROCKlemm
V
11

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.

Vichy answered 1/8, 2011 at 18:33 Comment(13)
We don't use forms authentication on this application, but we have run a scan on a different application using forms authentication and get the same problem.Cognition
Your report also says that ASP.NET SessionId is generally random and big enough - it says it must have at least 32 bits and the Session Id in ASP.NET is a lot bigger than that. Have you tried to see what the values for your cookies are? (using fiddler or firebug in mozilla)Vichy
Based on the linked articles in the OP, it sounds like this is exactly why this warning is appearing - they're triggering off of the 32 possible characters as being too narrow, without looking at the length or generation method.Gailgaile
I don't think 2^120 values are not enoughVichy
What I mean is, they're looking at the range of values within a single character instead of the overall range of the Id.Gailgaile
@Vasile, we actually used that exact code with the exception of the first line being "byte[] bytes = new byte[sizeof(Int64)];" and it still did nothing. Is it possible that IIS could be overriding something?Cognition
sizeof(Int64) is 8 which is a lot less than the default length.Vichy
Int64 is not enough for a session id, it is too small.Vichy
yeah, sounds like we might need to see some code. I agree with Vasile - 8 bytes is a far cry from 100.Gailgaile
Just implemented the 100 byte code and am waiting on a scan to finish.Cognition
Almost as secure as a GUID isn't saying much. GUIDs are designed to be globally unique, not cryptographically secure. Unique and predictable are not mutually exclusive. Many GUID algorithms are based on the current time and information about the machine to ensure that they are globally unique, but that also makes them reasonably guessable. A GUID algorithm may also not give resistance to reverse engineering the seed, which would make them HIGHLY predictable.Incongruent
@AJHenderson I agree, that was poor wording on my part. My point was that 120 bits of entropy, provided they are generated with a cryptographic RNG, should be enough protection against session id prediction. The GUID part was more of a comparison for data length.Vichy
I removed the GUID sentence.Vichy

© 2022 - 2024 — McMap. All rights reserved.