Salt is traditionally stored as a prefix to the hashed password. This already makes it known to any attacker with access to the password hash. Using the username as salt or not does not affect that knowledge and, therefore, it would have no effect on single-system security.
However, using the username or any other user-controlled value as salt would reduce cross-system security, as a user who had the same username and password on multiple systems which use the same password hashing algorithm would end up with the same password hash on each of those systems. I do not consider this a significant liability because I, as an attacker, would try passwords that a target account is known to have used on other systems first before attempting any other means of compromising the account. Identical hashes would only tell me in advance that the known password would work, they would not make the actual attack any easier. (Note, though, that a quick comparison of the account databases would provide a list of higher-priority targets, since it would tell me who is and who isn't reusing passwords.)
The greater danger from this idea is that usernames are commonly reused - just about any site you care to visit will have a user account named "Dave", for example, and "admin" or "root" are even more common - which would make construction of rainbow tables targeting users with those common names much easier and more effective.
Both of these flaws could be effectively addressed by adding a second salt value (either fixed and hidden or exposed like standard salt) to the password before hashing it, but, at that point, you may as well just be using standard entropic salt anyhow instead of working the username into it.
Edited to Add: A lot of people are talking about entropy and whether entropy in salt is important. It is, but not for the reason most of the comments on it seem to think.
The general thought seems to be that entropy is important so that the salt will be difficult for an attacker to guess. This is incorrect and, in fact, completely irrelevant. As has been pointed out a few times by various people, attacks which will be affected by salt can only be made by someone with the password database and someone with the password database can just look to see what each account's salt is. Whether it's guessable or not doesn't matter when you can trivially look it up.
The reason that entropy is important is to avoid clustering of salt values. If the salt is based on username and you know that most systems will have an account named either "root" or "admin", then you can make a rainbow table for those two salts and it will crack most systems. If, on the other hand, a random 16-bit salt is used and the random values have roughly even distribution, then you need a rainbow table for all 2^16 possible salts.
It's not about preventing the attacker from knowing what an individual account's salt is, it's about not giving them the big, fat target of a single salt that will be used on a substantial proportion of potential targets.
Predictable IVs can be exploited by chosen plain text.
Pretend that Eve is a DBA at an insurance company. The company collects medical histories from beneficiaries that include a lot of true/false check boxes about medical conditions. This company also happens to its own health insurance provider. Eve realizes that Alice could be blackmailed if she can discover that Alice has a particularly embarrassing medical condition. However, the value in each of these fields is encrypted, so even though Eve is the DBA, she only has access to the cipher text.
In CBC, the IV is XORed (noted by "⊕" below) with the plain text, then run through the block cipher: C1 = Ek(IV ⊕ P1).
Since Eve is a beneficiary of the insurance company, she can choose the plain text for her own medical record, and since she is the DBA, she can examine anyone's cipher text. In addition to using predictable IVs, the sloppy application developer did a poor job of validating the application inputs. If Eve can predict the IVs that will be applied to her (IVeve) and Alice's (IValice) records in advance, she can choose the plain text for her own record like this: Peve = IVeve ⊕ IValice ⊕ "false"
The application encrypts this plain text like this:
Ceve = Ek(IVeve ⊕ Peve) = Ek(IVeve ⊕ (IVeve ⊕ IValice ⊕ "false"))
The IVeve ⊕ IVeve cancels out, which means that Ceve = Ek(IValice ⊕ "false")
Now Eve can compare Ceve and Calice. If they are different, she knows that Alice must have entered "true" for that medical condition.
Making IVs unpredictable thwarts this attack, and an easy way to make them unpredictable is to choose them randomly after the plain text has been supplied.
Best Answer
Understanding Attack Vector
How HashMaps work
Say a comment form on a blog accepts the parameters – first_name, last_name, comment – as post parameters. Internally, Tomcat stores these parameters as a HashMap.
The logical structure of this HashMap is like this -
But the physical structure is different. The keys are first converted into a hashCode, and then the hashCode is converted into an array index.
The ideal physical structure thus becomes -
But the possible keys are infinite. So at some point, two keys will have the same hash code. This becomes a hash collision.
With collisions, the physical structure becomes :
Hash Collisions and impact on performance
When you have hash collisions, inserting a new entry means iterating over all the elements in a single hash "bucket" sequentially just to find out if it already exists in the map. Inserting one element can approach O(n) complexity if all elements hash to the same value. Inserting n elements in this worst case makes it O(n*n) complexity.
In short : If you insert thousands of keys that have the same hashCode, the server will require a lot of CPU cycles.
How do you generate keys with the same Hash?
In Java, "Aa" and "BB" have the same hash code.
Because of a property called "Equivalent Substrings", we can generate several other strings with the same hashcode, just by starting with these 2 strings.
First Iteration : "AAAA", "AABb", "BbAA", "BbBb" have the same hash code
Now, we have 4 strings with the same hash code. We can permute them to generate 16 strings that will have the same hash code. For example :
All these 16 strings have the same hash code.
You can now take these 16 strings, and generate 256 strings that have the same hashcode.
In short : It is very easy to generate a large set of strings that will have the exact hash code.
How do you attack the server?
Because this is just a POST request, an attacker can also use innocent browsers to attack a server. Just find a website with a cross site scripting vulnerability, embed code to make a POST request, and then use social engineering to spread the link to as many users as you can.
Prevention
In general, the underlying platform cannot fix this. This is considered to be a application framework problem. In other words, Tomcat has to fix this, not Oracle/Sun.
Possible fixes include :
Restrict the number of POST parameters - Tomcat 6.0.35+ has a new parameter maxParameterCount. The default value is 10,000. The lower the better, as long as it does not break your functionality.
Restrict the size of the POST request - For the attack to work, the Payload has to be huge. The default POST allowed by Tomcat is 2MB. Reducing this to say 200KB will reduce the effectiveness of this attack. The parameter in tomcat is maxPostSize
Web Application Firewall - If you have a web application firewall, you can configure it to block requests that look suspicious. This is a reactive measure, but is nice to have in case you cannot use one of the above solutions.
FYI - Tomcat's documentation is here - http://tomcat.apache.org/tomcat-6.0-doc/config/http.html