[#95] Multiple Content-Lengths

I've been talking to a few browser vendors about this off-list (and encouraging them to get involved on-list).

Two have indicated that they intend to implement as specified, although there's some agreement that a duplicate C-L can be ignored, as Willy has implemented.

There have also been questions about the text seeming to encourage implementers to display the content when there are mismatching C-L's; although it's written so they're not required to do so, it might be good to refine this a bit.

Two replied that they have concerns about displaying errors to end users. If they come on-list and discuss their concerns, we can discuss this more.

One hasn't replied.

Based on those discussions, I'm reopening issue #95, and making a straw-man proposal to kick off discussion:

Current (-11): 

   3.  If a message is received without Transfer-Encoding and with
       either multiple Content-Length header fields or a single Content-
       Length header field with an invalid value, then the message
       framing is invalid and MUST be treated as an error to prevent
       request or response smuggling.  If this is a request message, the
       server MUST respond with a 400 (Bad Request) status code and then
       close the connection.  If this is a response message received by
       a proxy or gateway, the proxy or gateway MUST discard the
       received response, send a 502 (Bad Gateway) status code as its
       downstream response, and then close the connection.  If this is a
       response message received by a user-agent, the message-body
       length is determined by reading the connection until it is
       closed; an error SHOULD be indicated to the user.

Proposed:

   3.  If a message is received without Transfer-Encoding and with
       either multiple Content-Length header fields indicating different
       lengths or a single Content-
       Length header field with an invalid value, then the message
       framing is invalid and treated as an error to prevent
       request or response smuggling.  If this is a request message, the
       server MUST respond with a 400 (Bad Request) status code and then
       close the connection.  If this is a response message received by
       a proxy or gateway, the proxy or gateway MUST discard the
       received response, send a 502 (Bad Gateway) status code as its
       downstream response, and then close the connection.  If this is a
       response message received by a user-agent, it SHOULD NOT
       be used, but if it is the message-body
       length is determined by reading the connection until it is
       closed, and the user SHOULD be informed of the problem. 
       Subsequent responses on the connection MUST NOT
       be used.


Also, FYI:
  https://bugzilla.mozilla.org/show_bug.cgi?id=597706

Cheers,



On 15/09/2010, at 3:33 PM, Willy Tarreau wrote:

> On Wed, Sep 15, 2010 at 01:44:15PM +1000, Mark Nottingham wrote:
>> If lots of implementations are breaking in obvious ways because of duplicate headers, it will encourage those broken intermediaries to fix themselves.
> 
> In general it's the last installed component which is declared faulty and
> which must adapt, at least for the time required to fix the first one. I
> had to do that in haproxy several times (relax header names checks, extend
> cookie parsing, etc...). But I tend to agree with the goal of cleaning up
> existing implementations.
> 
>> However, we should discuss how UAs will display such errors to users. 
>> 
>> Currently, the language implies that the content is displayed to the user by the UA, as well as (SHOULD) an error message. Will that SHOULD get implemented? 
>> 
>> If not, intermediaries will get bug reports because a site sending two C-L headers will work with browsers, but won't work when an intermediary is interposed -- incenting them not to implement.
>> 
>> A few possible fixes:
>>  0) status quo -- UA vendors are happy to display an error to the user, because this type of error is so rare. (UA vendors?)
>>  1) UA required NOT to display / make available content with multiple C-L headers, giving parity with intermediaries (if they implement).
>>  2) Change requirement to focus on not using any more messages after this one in the connection, as they're tainted. 
> 
> That last point is a bit dangerous IMHO. My fears are that some people who
> implement intermediaries decide to do that as an acceptable fallback solution.
> If their implementation forwards the message assuming the max of the two as
> the body length, the next hop may very well accept the shorter length and
> ignore the rule, thus effectively process two messages.

I was speaking just about user-agents, not other implementations.

> 
> I think it is reasonable to distinguish between two cases :
> 
>  - duplicate C-L
>  - different C-L
> 
> The former may result from stupid programming but should be harmless,
> because whatever the C-L the implementation uses (first, last, max, min),
> the result remains the same.
> 
> The second may result from attacks or from early bugs. But it already does
> not work equally through various components. For instance, firefox takes
> the last one. From memories, Squid takes the max. Apache takes the first
> one (just checked). So the end result is that such an anomaly can't live
> long. I think that's why all times I encountered two C-L, they were
> duplicates that remained unnoticed.
> 
> In my opinion, we should make it mandatory to reject a message with multiple
> different C-L headers. It's too dangerous and has no valid reason to be met.
> The case of the duplicates can then either be rejected because it's nothing
> but as a special case of the multiple C-L, or be specifically accepted
> because it's harmless, if the implementation wishes to perform this specific
> test.
> 
> Regards,
> Willy
> 
> 


--
Mark Nottingham     http://www.mnot.net/

Received on Monday, 20 September 2010 05:58:30 UTC