- From: Willy Tarreau <w@1wt.eu>
- Date: Wed, 14 Jul 2010 09:28:13 +0200
- To: Julian Reschke <julian.reschke@gmx.de>
- Cc: HTTP Working Group <ietf-http-wg@w3.org>
Hi, On Tue, Jul 13, 2010 at 08:18:10AM +0200, Julian Reschke wrote: > <http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-10#appendix-D.11> In this one we would need to add a bit of clarifications about the value domains that may be used for integers. I have identified 2 situations where we can encounter integer overflows, with either just impossibility to transfer data, or more important, security issues : - 6.2.1. Chunked Transfer Coding chunk-size = 1*HEXDIG - 9.2. Content-Length Content-Length-v = 1*DIGIT In both cases, we don't indicate any minimal size requirement. It looks like both values are generally assumed to be 31 or 32 bits depending on signedness. BTW, I've once been unable to download a DVD image from a site because the announced content length was wrong due to integer overflow. I don't remember what server it was though :-/ I think it is difficult to ask every implementation to support at least XXX bits, but we should at least add as a strict requirement that any agent along the chain must detect integer overflows when parsing or printing these values, and must abort processing if this happens. My main concern here is a security issue. If an intermediary supports more bits than a server, it may forward a larger body than the server believes is sent, and push "invisible" requests to the server. For instance : POST /harmless HTTP/1.1 Host: victim Content-length: 4294967302 # = 2^32 + 6 Hello POST /login.jsp HTTP/1.1 Host: victim Content-length: 20 user=foo1&pass=bar1 POST /login.jsp HTTP/1.1 Host: victim Content-length: 20 user=foo2&pass=bar2 etc... The reverse-proxy reads "Content-length: 4294967302", parses it as a 64 bit value and starts forwarding that many bytes. The server parses it as a 32 bit value, overflows and expects 6 bytes (4294967302 mod 2^32 = 6). It then reads the "Hello\n" message and takes the next pending data as a new valid request. The same issue happens if the intermediary parses the value as an unsigned 32bit value while the server parses it as a signed 32 bit value, which will be negative for lengths >= 2^31. #9.2 states that "Any Content-Length greater than or equal to zero is a valid value". The risk I see here is that this is translated in the code as "Consider the content-length only if >= 0", resulting in no body for negative values. The same problem as above then appears. I'm just realizing something else. Some implementers might be tempted to use strtoul() or equivalent to reliably parse these values and detect errors. The definition of those values with 1*DIGIT suggests that leading zeroes are allowed. Special care must be taken to ensure that the decoding is forced to base 10, otherwise a number such as 0123 may be automatically interpreted as the octal value for the decimal 83. Regards, Willy
Received on Wednesday, 14 July 2010 07:28:42 UTC