Skip to content

Should servers interpret Transfer-Encoding in 1.0 requests? #879

Description

@mattiasgrenfeldt

The Transfer-Encoding header was first introduced in version 1.1. So one would assume that 1.0 servers should not interpret it. But in RFC 7230 the following paragraph was introduced under section 2.6:

The interpretation of a header field does not change between minor
versions of the same major HTTP version, though the default behavior
of a recipient in the absence of such a field can change. Unless
specified otherwise, header fields defined in HTTP/1.1 are defined
for all versions of HTTP/1.x. In particular, the Host and Connection
header fields ought to be implemented by all HTTP/1.x implementations
whether or not they advertise conformance with HTTP/1.1.

This paragraph suggests that 1.0 servers should interpret the Transfer-Encoding header. This paragraph also exists in the current draft version of the Semantics spec. Later in RFC 7230 however, under section 3.3.1, we see the following paragraph:

Transfer-Encoding was added in HTTP/1.1. It is generally assumed
that implementations advertising only HTTP/1.0 support will not
understand how to process a transfer-encoded payload. A client MUST
NOT send a request containing Transfer-Encoding unless it knows the
server will handle HTTP/1.1 (or later) requests; such knowledge might
be in the form of specific user configuration or by remembering the
version of a prior received response. A server MUST NOT send a
response containing Transfer-Encoding unless the corresponding
request indicates HTTP/1.1 (or later).

This paragraph suggests that it is ok for implementations that only support 1.0 to not implement the Transfer-Encoding header.

Taken together, these two paragraphs tell us that servers which implement both 1.0 and 1.1 should in their 1.0 implementation interpret Transfer-Encoding. While servers which only implement 1.0 should not. Let's call these two different behaviors the 1.1-behavior and the 1.0-behavior respectively.

If we have a setup with a reverse proxy (gateway) which has the 1.0-behavior in front of a server with the 1.1-behavior, then HTTP Request Smuggling is possible, but both systems follow the specification. If the following request is sent to the proxy:

GET / HTTP/1.0
Host: example.com
Content-Length: 50
Transfer-Encoding: chunked

0

GET /smuggled HTTP/1.0
Host: example.com

Then the proxy will ignore the Transfer-Encoding header, but forward it as-is. The proxy will instead interpret the Content-Length header and see the second GET as the body of the first one. The server will instead interpret and prioritize the Transfer-Encoding header and will therefore see two different requests.

While looking for Request Smuggling in various proxies and servers we have observed three different behaviors in the wild.

  • Most systems adopt the 1.1-behavior.
  • One server adopted the 1.0-behavior.
  • One proxy adopts a mix between the 1.1-behavior and the 1.0-behavior. The system ignores Transfer-Encoding but never forwards it together with the Content-Length header, making the smuggling attack impossible.

If a proxy with the 1.0-behavior is discovered, then request smuggling is possible, but there is no bug, since both parties follow the RFC. Should the spec somehow be changed/clarified to avoid this?

(Authors: Mattias Grenfeldt and Asta Olofsson)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions