Bug 15859 - wrong Content-Length header is forwarded when de-chunking
Summary: wrong Content-Length header is forwarded when de-chunking
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy (show other bugs)
Version: 2.0-HEAD
Hardware: All All
: P3 normal with 5 votes (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL: http://coad.measurement-factory.com/c...
Keywords:
: 11993 31454 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-01-07 21:01 UTC by Co-Advisor
Modified: 2007-09-01 12:12 UTC (History)
4 users (show)



Attachments
test case trace (6.15 KB, text/html)
2003-01-07 21:02 UTC, Co-Advisor
Details
fresh test trace (7.34 KB, text/html)
2005-06-03 23:48 UTC, Co-Advisor
Details
security fix for C-L vs T-E handling (Joe Orton, CVE CAN-2005-2088) (1.17 KB, patch)
2005-08-26 16:07 UTC, Jan Kratochvil
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Co-Advisor 2003-01-07 21:01:22 UTC
Looks like a possible RFC 2616 MUST violation. 
Apache decodes chunked encoding correctly but
forwards wrong Content-Length header which now MUST
be honored since Apache removed chunked encoding.
Thus, the overall result is that a compliant client
would see truncated content (e.g., $100 instead of $1000)
because of how Apache changed the message it was
forwarding.

See attached trace for details and ways to reproduce.

Test case IDs in the trace link to human-oriented test case
description and RFC quotes, if available.
Comment 1 Co-Advisor 2003-01-07 21:02:06 UTC
Created attachment 4352 [details]
test case trace
Comment 2 Graham Leggett 2003-04-15 17:32:23 UTC
Is the following sentence correct?

"A proxy MUST remove a Content-Length header from chunked responses, in case
this content length header is wrong".
Comment 3 Co-Advisor 2003-04-15 17:50:45 UTC
Not exactly, but very close, IMO.

The proxy MUST ignore wrong Content-Length header in chunked
responses (which is what Apache is probably doing). It would
be OK to forward that header, provided that the proxy does
not decode chunks on-the-fly. A compliant recipient would
not have a problem handling such a response (chunked
encoding with wrong Content-Length header).

However, Apache decodes chunks into "normal" (identity)
encoding and forwards the response with the original (wrong)
Content-Length value. While there is no specific MUST about
this case, the only logical interpretation or RFC 2616
suggests that the wrong Content-Length header must be
removed. Otherwise, a compliant recipient will mis-interpret
the response!

If you want a one sentence summary, I would say: "A proxy
has to remove the wrong Content-Length header when
forwarding a chunked response using identity encoding (i.e.,
when de-chunking on-the-fly)."
Comment 4 Graham Leggett 2003-04-15 17:57:34 UTC
The problem though is that we cannot know the Content-Length is wrong until we
have processed the entire request. At this point we would have already sent the
Content-Length header onwards, so it's too late to fix it if it is wrong - it
would require the proxy to buffer the entire request before sending it on, which
is not practical.

One possible thing to do though is to remove the Content-Length header should
Apache decide to send chunked encoding. This needs to be done inside the filter
responsible for chunking, rather than mod_proxy.

Thoughts?
Comment 5 Co-Advisor 2003-04-15 18:05:11 UTC
The Content-Length header is _always_ wrong when it is used together
with chunking because Content-Length header is defined to represent
both entity-length and the transfer-length. It is not possible to represent both with a single value when chunking is used.

Thus, only two actions would be correct, IMO:
   - leave wrong Content-Length header and do NOT de-chunk
   - remove wrong Content-Length header

Note that there is no need to remove Content-Length header if Apache decides to send chunked encoding. It is de-chunking that causes the problem.
Comment 6 Cymen Vig 2003-07-26 22:08:31 UTC
Is this related to:
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21348>

If so, this bug breaks WindowsUpdate when used behind mod_proxy. Patch is linked
in above bug that might be applicable.
Comment 7 Co-Advisor 2003-08-15 21:37:06 UTC
The WindowsUpdate patch you mentioned has no visible effect
on this bug. Note that the patch seems to be designed to
affect HEAD responses while this bug deals with GET responses.
Comment 8 Nick Kew 2004-09-28 19:13:06 UTC
*** Bug 31454 has been marked as a duplicate of this bug. ***
Comment 9 Nick Kew 2004-11-26 11:31:33 UTC
*** Bug 11993 has been marked as a duplicate of this bug. ***
Comment 10 Kristian Nielsen 2004-11-26 12:03:10 UTC
I believe that this problem relates to proxying of _all_ requests with
chunked request data, not just those with a bogus Content-Length.

mod_proxy is de-chunking and removing Transfer-Encoding: chunked, forwarding
a request with neither Content-Length: or Transfer-Encoding: header. This
causes the downstream server to reply with error 411 "Length Required".

Bug 11618 has a network trace showing this clearly.

Since it is not possible to send a correct Content-Length header without
buffering all request data, it seems to me that the proper fix is to not
de-chunk if the original request is chunked?

I looked briefly in the function ap_proxy_http_request in proxy_http.c.
How about if the original request uses chunked transfer-encoding, then
the proxied request is also send as chunked? I could try to create a patch
to add that to the code, it seems not too hard:

    /* send the request data, if any. */
    seen_eos = 0;
    do {
        status = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
                                APR_BLOCK_READ, HUGE_STRING_LEN);

        if (status != APR_SUCCESS) {
            return status;
        }

        /* If this brigade contain EOS, either stop or remove it. */
        if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
            /* As a shortcut, if this brigade is simply an EOS bucket,
             * don't send anything down the filter chain.
             */
            if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
                break;
            }

            /* We can't pass this EOS to the output_filters. */
            e = APR_BRIGADE_LAST(bb);
            apr_bucket_delete(e);
            seen_eos = 1;
        }

        e = apr_bucket_flush_create(c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(bb, e);

        status = ap_pass_brigade(origin->output_filters, bb);
        if (status != APR_SUCCESS) {
            ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
                         "proxy: pass request data failed to %pI (%s)",
                         p_conn->addr, p_conn->name);
            return status;
        }
        apr_brigade_cleanup(bb);
    } while (!seen_eos);
Comment 11 Jan Kratochvil 2004-11-26 12:30:23 UTC
You do not need to code it as httpd-2.1 has it already fixed.
I also backported it in the patch of Bug 31454 which was apparently a DUPE, you
can repost the patch here if you wish.
I am using my patch on my server for: Fedora Core 3 httpd-2.0.52-3.1
Comment 12 Jeff Trawick 2005-01-07 19:47:50 UTC
I've been working on some improvements to the current solution in Apache 2.1.  A
backport of my current 2.0 code is in a patch at
http://www.apache.org/~trawick/20proxyreqbody.txt
The version of this for Apache 2.1-dev is in the proxy-reqbody branch in subversion.
.
Any comments or additional testing would be appreciated.
Comment 13 Jan Kratochvil 2005-02-02 18:18:04 UTC
The current version of http://www.apache.org/~trawick/20proxyreqbody.txt
successfully tested on SonyEricsson P900 (sorry for the response time as I do
not have the device available). <bite>Patch version-name change on its content
change would be preferred.</bite>
Comment 14 Jeff Trawick 2005-02-02 19:13:29 UTC
>Patch version-name change on its content change would be preferred.

good idea for the future...

and thanks for the test report!  I assume that some type of upload from the
phone would not work through mod_proxy without this patch????
Comment 15 Jan Kratochvil 2005-02-02 19:32:00 UTC
SonyEricsson P900 uses buzzword WAP-2.0 which no longer transfers WAP/WML over
WSP/WTP protocols but it started using HTTP/TCP. P900 will interpret WAP-1.x WAP
gateway settings sent over SMS as HTTP proxy for its WAP-2.0 (IMO incorrectly).
During MMS send operation P900 will send chunked POST, current mod_proxy will
dechunk it but it will not fill in the Content-Length making the final head+body
POST request combo invalid. See (I could no longer find the TCP snaps):
http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=109186315924289
Comment 16 Jeff Trawick 2005-05-21 14:54:33 UTC
fix committed to 2.0.next
Comment 17 Co-Advisor 2005-06-03 23:48:50 UTC
Created attachment 15295 [details]
fresh test trace

Sorry, but the current http://www.apache.org/~trawick/20proxyreqbody.txt
fix does not solve the problem. Patched Apache httpd-2.0.54 is still
sending
    Content-Length: 15
when the [dechunked] content is actually 20 bytes. 
Please see the attached fresh trace.
Are we testing with the wrong fix?
Comment 18 Co-Advisor 2005-06-03 23:50:45 UTC
I am taking the liberty of reopening this bug
because the test case still fails (see above).
Comment 19 Jeff Trawick 2005-06-04 00:46:48 UTC
btw, the proxy-reqbody patch did not affect the response processing...

any idea what is required to have the origin server send both Content-Length
*and*  Transfer-Encoding?
Comment 20 Joe Orton 2005-06-04 10:55:34 UTC
Sending both would violate 2616, if the proxy receives a message with both C-L
and T-E it MUST ignore the C-L header per comment 3.
Comment 21 Jan Kratochvil 2005-08-26 16:07:56 UTC
Created attachment 16218 [details]
security fix for C-L vs T-E handling (Joe Orton, CVE CAN-2005-2088)

Just FYI Joe Orton fixed: Fedora Core Bug:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=162245
, the same as Red Hat Enterprise Bug:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=162244
but unfortunately these patches will disable the funtionality of:
http://www.apache.org/~trawick/20proxyreqbody.txt
as presented here in Comment #17 .
Reverting its first part restores 20proxyreqbody.txt back as WORKSFORME,
Not sure if its second part resolves the issue of Comment #17 .
Comment 22 Nick Kew 2007-07-31 18:19:34 UTC
Is this still open?  It appears to be fixed in trunk at least.
Comment 23 Nick Kew 2007-09-01 12:12:36 UTC
OK, tested in 2.2.5; the proxy removes the Content-Length.