Re: [#95] Multiple Content-Lengths

On Wed, Oct 13, 2010 at 09:47:26AM +1300, Adrien de Croy wrote:
(...)
> >I'm realizing that this is very similar to the chunked-encoding with
> >content-length. I wonder whether we have numbers on the cases where
> >this still happens, because the risks of bad handling are exactly the
> >same, even though the spec says that chunking must be assumed in this
> >case. It would be nice if numbers showed that we could simply consider
> >that situation as an error.
> >
> 
> I agree.  The current spec presumes it's an innocent error that a 
> Content-Length header sneaked in, and really it's meant to be chunked if 
> there's a Transfer-Encoding: chunked header.
> 
> However for any other problem scenario, this leads to other issues which 
> show up as malformed chunks if you're lucky.
> 
> I'm struggling to see how this could be used in an attack though.

I'm thinking about requests. Since the Apache chunked encoding exploits
a few years ago, we realized that chunked encoding is almost unused in
requests. Some products even consider that as an attack on the old Apache
vulnerability. So I suspect that we might find products which simply
ignore chunked encoding in a request, or maybe ignore it if there's a
content-length.

Also, chunking appeared with HTTP/1.1. If we send an HTTP/1.0 request to
a component with a "transfer-encoding: chunked" header, I guess that we'll
observe various behaviours. Some products might consider chunking despite
the version, others might ignore it due to the version.

Now, for responses, my guess is that if we start from an example Adam has
suggested on hybi concerning shared hosting environments, we could imagine
an attacker's server building a response that's interpreted by a browser as
a short one, but by intermediaries as a larger one, then we can have the
browser reuse the connection for a second request to the victim's site,
which will use as a response the payload of the first one. For instance :

GET / HTTP/1.1
Host: attacker.com

	HTTP/1.1 302 Found
	Location: http://victim.com/	(same ip:port as attacker)
	Content-length: 200		(covers next fake response for intermediary)
	Transfer-encoding: chunked

	0				(end of data for spec-compliant browser)
	HTTP/1.1 302 Found
	Location: /			(reconnect to clean up the mess)
	Connection: close
	Set-Cookie: sessionid=123456; path=/
	Content-length: 0

GET / HTTP/1.1
Host: victim.com

browser may then use the unread data above just after the '0', and use it
as a valid response, believing it's really connected to victim.com.

Maybe this is stupid and cannot work for some reasons I've overlooked,
but at first glance I can't see a failure here. It only relies on an
intermediary to ignore the Transfer-encoding header (eg: a pre-1.1
proxy, we'd probably have to explicitly set "Connection: keep-alive"
in the request then).

While it might be used accidentely from a browser, we could also imagine
that an attacker could be on the client side too, and forge such requests
in order to populate an intermediary's cache with forged contents for the
victim's site. In such a case, I fear that there's no solution if the
cache is the only intermediary and it's not spec-compliant :-/

Regards,
Willy

Received on Wednesday, 13 October 2010 03:28:05 UTC