Most Java JVMs are subject to a very severe Denial of Service (all Oracle/Sun JVMs pre 1.6.0_24 [that ain't out yet at the time of this writing] and that didn't get the HotFix that came out yesterday, for example).
http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
The following:
curl -H 'Accept-Language: en-us;q=2.2250738585072012e-308' http://example.org
crashes a lot of the Tomcat webservers on the planet.
My question is simple: who's at fault?
Apparently getLocale()
calls the (very badly) bugged Double.parseDouble(...)
and you can then trivially perform a Denial of Service on Tomcat.
Is the bugged implementation of Double.parseDouble(...)
really at fault?
To me it looks like the real issue is that the HTTP specs are using floating-point numbers for something that really doesn't look very much like scientific computation to me. Using floating-point number for such a thing seems more than weird: it is easy to prove that implementation in different language shall give different results.
So who's at fault?
Java's terribly lame (bug was known since 10 years) implementation of Double.parseDouble(...)
?
The HTTP specs? (remember that PHP suffered the exact same bug).
I can understand you blame the language if it happens with one language... But when two remote Denial of Service attacks happens to two different languages due to the fact that the HTTP specs dictate parsing of floating-point number for something that is not a scientific computation should ring a bell.
Floating-point numbers should only ever be used for scientific computations. If you don't have floating-point numbers and no epsilon, you're doing it wrong.
Actually, rfc 2616 (the HTTP/1.1 spec) says:
Note that this limits the number of digits and does not allow an exponent. I'd think any implementation would be perfectly within the spec to disregard input that has more than 3 fractional digits, and completely ignore anything with an exponent value. The fact that Tomcat doesn't do this is not a problem with the HTTP spec.
This is a problem with the number parsing method in the Java runtime library, not Tomcat - it just use said method.
Edit: The reason why q is a fraction is because it allows you to use a value between two existing values, which may be necessary when providing a value after the initial assignments have happened.
It's not either/or. As with many security problems, it's a result of both of them being at fault. If either one had done their job reasonably well, the problem would never have arisen.