Most unpatched Tomcat webservers are vulnerable, w

2020-06-16 08:35发布

问题:

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.

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.

回答1:

Actually, rfc 2616 (the HTTP/1.1 spec) says:

HTTP/1.1 applications MUST NOT generate more than three digits after the decimal point. User configuration of these values SHOULD also be limited in this fashion.

qvalue    = ( "0" [ "." 0*3DIGIT ] )
          | ( "1" [ "." 0*3("0") ] )

"Quality values" is a misnomer, since these values merely represent relative degradation in desired quality.

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.



回答2:

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.



回答3:

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.