[NEW ISSUE] Content-Length and Transfer-Encoding: security implications

Dear ietf-http-wg members,

This is to reopen the issue submitted on 22 NOV 2007 by Bjoern Hoehrmann
(http://lists.w3.org/Archives/Public/ietf-http-wg/2007OctDec/0264.html),
on this time as a security issue.

In Section 4.4 of <draft-lafon-rfc2616bis-latest> (as of 03 DEC 2007), 
there is a description as follows:

> Messages MUST NOT include both a Content-Length header field and a 
> transfer-coding. If the message does include a transfer-coding, the 
> Content-Length MUST be ignored.

However, this specification makes interoperability security problem with 
HTTP/1.0 clients/servers.

The original post by Bjoern noted this as a general problem, but this 
has been one of the reason which caused Mozilla security issue #297078 
(https://bugzilla.mozilla.org/show_bug.cgi?id=297078), reported in July 
2005 by me.  This causes "request splitting" vulnerability.

Imagine that there is the following request stream:

  POST /a HTTP/1.0
  Host: hostname.domain.name.jp
  User-Agent: Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.7.8) Gecko/20050513
  bian/1.7.8-1
  Keep-Alive: 300
  Connection: keep-alive
  Transfer-Encoding: chunked
  Content-Type: text/xml
  Content-Length: 113
  
  0
  
  POST /~yutaka/cgi-bin/test2.cgi?exploit=yes HTTP/1.0
  Host: hostname.domain.name.jp
  Content-Length: 500
  

The client sent only one valid request to the server: in HTTP/1.0, 
"Transfer-Encoding" header is an extension entity header and is allowed. 
However, if an HTTP/1.1 server examines this, it will be interpreted as 
TWO requests: now Transfer-Encoding is a defined entity header, and due 
to the rule the server MUST parse it as two requests.

The same problem will occur with responses, too. For example, an 
HTTP/1.0 server with CGI capability can make valid HTTP/1.1 clients 
misunderstand the response boundary.  In this case, if there is either 
virtual hosting or a proxy,  the attacker host can inject any data 
including scripts to contents of another host, which is called 
"cross-site content injection vulnerability".  The attacked site cannot
prevent this to happen by their own means.

In current phrasing of the RFC2616, it is generally understood as: if 
both headers are present, the requested behavior is to accept the 
message by discarding Content-Length header. Many servers/clients seems 
to be implemented in this way, but it is a very bad practice. I think 
that the clause in Section 4.4 should be updated to something like 
either of the following:

(case 1: my recommendation is the stronger requirement)
> Messages MUST NOT include both a Content-Length header field and a 
> transfer-coding. If a request does include both, the server MUST 
> return 400 (Bad Request) and close the connection.
> If a response includes both, the client MUST ignore any data sent and
> close the connection immediately.

or (case 2: if it is inappropriate to add any new MUST-type restriction 
in rfc2616bis)

> Messages MUST NOT include both a Content-Length header field and a 
> transfer-coding. If the message does include a transfer-coding, the 
> Content-Length MUST be ignored.  The server SHOULD return 400 (Bad 
> Request) for such requests.  The client SHOULD NOT accept any responses 
> following such an invalid response in a keep-alive connection, and MAY 
> reject such a response.

A similar description in the item 3. in the same section should also
be updated.

-- 
Yutaka OIWA, Ph.D.                                       Research Scientist
                            Research Center for Information Security (RCIS)
    National Institute of Advanced Industrial Science and Technology (AIST)
                      Mail addresses: <y.oiwa@aist.go.jp>, <yutaka@oiwa.jp>
OpenPGP: id[995DD3E1] fp[3C21 17D0 D953 77D3 02D7 4FEC 4754 40C1 995D D3E1]

Received on Tuesday, 4 December 2007 18:15:41 UTC