Hi André, > -----Original Message----- > From: André Warnier [mailto:a...@ice-sa.com] > 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: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org