Hi André,
> -----Original Message-----
> From: André Warnier [mailto:[email protected]]
> Sent: Tuesday, May 27, 2014 3:06 PM
>
> Mark Thomas wrote:
> > CVE-2014-0097 Information Disclosure
> >
> ...
>
> >
> > Description:
> > The code used to parse the request content length header did not check
> > for overflow in the result. This exposed a request smuggling
> > vulnerability when Tomcat was located behind a reverse proxy that
> > correctly processed the content length header.
> >
>
> I believe you, but I must admit that I don't really get what the problem is,
> here.
> If someone feels like explaining..
The fix for this issue also made me a bit curious (I don't know the background
of the issue).
The old code for parsing the Content-Length header looked like this:
long n = c - '0';
long m;
while (--len > 0) {
if (!isDigit(c = b[off++])) {
throw new NumberFormatException();
}
m = n * 10 + c - '0';
if (m < n) {
// Overflow
throw new NumberFormatException();
} else {
n = m;
}
}
Where "b" is a byte-array containing ASCII decimal chars.
The code parses a decimal number like "123" by multiplying the current number
(e.g. 12) by 10 (=120), then adding the next character (=123).
To check for an overflow, it checks if the "new" number is lower than the old
one. Usually, when making a simple addition with positive numbers where the
second one is low (0-9), this is enough as for an overflow, the first bit will
go to 1, so the number is negative. E.g., when using signed bytes (8 bits):
0111111b (127) + 3 = 10000010b (-126)
However, the code above also does an multiplication by 10. For example, if the
current number (signed long) is 6148914691236517205 (binary:
101010101010101010101010101010101010101010101010101010101010101b) and the next
character is '3', the calculation would be:
101010101010101010101010101010101010101010101010101010101010101b
(6148914691236517205) * 1010b (10) =
101010101010101010101010101010101010101010101010101010101010010b
(6148914691236517202)
101010101010101010101010101010101010101010101010101010101010010b
(6148914691236517202) + 11b (3) =
101010101010101010101010101010101010101010101010101010101010101b
(6148914691236517205)
In this case, the new number would == the old number, so the code " if (m < n)"
would not detect the overflow.
E.g., if you run following code:
long a = 6148914691236517205L;
long b = a * 10 + 3;
System.out.println(a == b);
it will print "true".
However, I don't know if such example is really the one that causes issues, as
this number is pretty high (but I did not found how smaller numbers could cause
overflows not to be detected). Maybe someone could comment on that.
Thanks!
Regards,
Konstantin Preißer
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]