-----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

Reply via email to