Re: HTTPbis -10 drafts published

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