In .NET 4.5 it’s possible to optionaly use randomized string hash code generation.
That means, that hash codes for the same string calculated in different application domains will be different. (See http://msdn.microsoft.com/en-us/library/jj152924.aspx)
The question is: what is the practical use of this option?
In other words, in what scenario (scenarios) do I need to switch it on?
I believe that the general application of this is to prevent possible DoS attacks against the hashing mechanism.
Since
GetHashCode()is used internally by things likeDictionary<,>, and for “normal” data, the hash values should be reasonably well distributed so that hash collisions don’t occur “too often”. When a hash collision does occur, theDictionary<,>falls back to a linear search of all items with the same hash code.In a publicly accessible application, it may be possible for an adversary with knowledge of the hashing mechanism, to submit requests with large numbers of strings with identical hash codes, resulting in a normally O(1) lookup becoming an O(N) lookup for any dictionary that has these values added to it.
For web applications specifically, I believe that things like headers, and query string parameters are added to dictionaries for quick access by the application, as such the adversary could submit a request with thousands of parameters with colliding hashes, resulting in the request being significantly more resource-hungry than a “normal” request. This has an amplifying effect on any DoS attempt, allowing an attack to take place even when the attacker has only relatively modest bandwidth available.
By randomizing the hash value per AppDomain, it is less likely that an attacker can craft strings with colliding hashes, so preventing such an attack.
Edit addressing comments:
Whilst the MSDN article doesn’t mention it, the intention of the setting isn’t about providing a means to have different AppDomains create different string hashes, it’s a security feature to prevent a third party from creating many strings with identical hashes.
Prior to .NET 4.5 (or with this setting disabled), providing that I was running the same .NET version as you,
"some string".GetHashCode()on my machine would give the same value as on yours. Since the hashing mechanism used is simple, (and certainly not a cryptographically secure hash), it’s relatively easy to reverse engineer and create lots of strings with identical hashes, then use these as described above to amplify a DoS attack.With this setting enabled, an element of randomness is added to the hash code generation for strings, making it much more difficult for an attacker to craft colliding strings reliably.
The fact that it’s per-AppDomain is a by-product of the fact that hash codes have certain required properties, e.g. two identical strings have identical hash codes. The AppDomain therefore provides a sensible boundary for the effects of the setting in that most applications will run perfectly fine with this setting enabled.
This new setting likely further addresses issues raised in this vulnerability disclosure: CVE-2011-3414 related to exploiting hashing collisions in ASP.NET applications (the issue was “fixed” in other .NET versions, I believe, by limiting the number of keys that could be supplied in the request, preventing an attacker from creating so many collisions that performance was significantly degraded). The referenced paper specifically mentions the lack of randomized string hashing as a factor contributing to the widespread nature of the issue.