-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Mark,
On 5/27/14, 10:32 AM, Mark Thomas wrote: > On 27/05/2014 15:12, Konstantin Preißer wrote: >> 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-0099 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. > > Yes, you need to have a content-length above Long.MAX_VALUE for > problems to occur. That would be unusual to say the least for most > (all?) applications in normal usage but easy for a malicious user > to set. > > If the proxy handles the header correctly, the attacker is going to > have to send a *lot* of data to get this to work. Where things > would get interesting is if the proxy and Tomcat both had parsing > issues but ended up with different values. That would make request > smuggling a lot easier. > > Something else to consider. If an attacker can trigger this > "request/response offset" then any subsequent requests they make > could receive responses that contain data from other users. Even if > they can't control what that data is, that is still information > disclosure. It's worth pointing out that one of the mitigations of this vulnerability is to configure the proxy to reject very large values for Content-Length. For instance, we don't expect any file uploads, etc. larger than a few MB. So for httpd, we could do something like this: SetEnvIf "Content-Type" ".{10,}" no-jk=1 This will refuse to send any requests via mod_jk if they have Content-Type headers whose values are 10 or more characters. We do the same thing for Accept-Language for a bug that has been long-since fixed I think. It's probably worth publishing that mitigation since it's easier to do than upgrading Tomcat if it's an emergency. - -chris -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJThNtUAAoJEBzwKT+lPKRY75AP/iyC/mb1S+JgVkcWid/Xqsn5 RfSPLMmT5G+yVSBiWRa9P8Rp3Tg1FE63aQtr0ybLCwh/ds4RXapbkNQATyXeAwgf viwLpE7iuzS4SQs18zSh60jaEdKJh9MrCrc2YL5gTq2crcJMz9s8PKOmtZQ/kY1e T71BlvPef5GHkzjWMfVEodMubtOWnp346COeFtDdJpi8zzJ3/Zh9YBLBAXW+aqNh 8qxq0SEZchrgiFmfuP83A59JOzHm8xz3QOf2SjHEitYE5kOo3t+zyTIOZRAlh0Ka poegWmpEKd94/GiyxkH5OfbqwDjFdg8tb/acm+4PX6aZiXyx5K3Ri4pIji64llEw jJCx6RSNgAkgjt8206TGV09tkCrtym7sACyQ6afl8kQQlPWVPitzpk/4ITzwtoRR WieZc4yAsp03sT85Ti3xwUstvhANcHXn0ltc6JNH3mvOHfLnTScKoJA7s6nLyDuN NTKhNHc9Rm1hHz0Kpuf/AHl9jgD1hFB8qpLMl0P570+yzALeiM4So+46/6dfTqtR 7N+Ngh3TElIpuMPkzXHg5KQNi3Nz4tKA9Gaytg70dDBV0u0GVTVEwBD9UIWo72oT /BNI0UUIC5Xg5ER/JIgwPErmg6RFlTNE+rCUrxMzreFjVfLq1YtUNL0OBbqxD9/B J/79gZcvBPsvGvGlIU+D =Osrg -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org