diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2019-10-06 15:14:05 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2020-01-26 00:41:04 -0500 |
commit | 66624b375b6f1ceae446ba09d55f123683506337 (patch) | |
tree | daa1164dd120c1805746ff6ff2d15a0db83f990e /src/request.c | |
parent | 61f85d14ee4444755e0771495b97af11162448dd (diff) | |
download | lighttpd-git-66624b375b6f1ceae446ba09d55f123683506337.tar.gz |
[core] reject Transfer-Encoding + Content-Length (#2985)
reject requests with both Transfer-Encoding and Content-Length
as recommended in RFC 7230 Section 3.3.3.
strict header parsing is enabled by default in lighttpd. However,
if explicitly disabled in lighttpd.conf, lighttpd will continue to
accept Transfer-Encoding and Content-Length in the same request,
and will ignore (and remove) Content-Length before passing to backend.
UNSAFE: server.http-parseopts = ( "header-strict" => "disable" )
This is NOT RECOMMENDED since doing so disables other protections
provided by lighttpd strict http header parsing.
RFC7230 Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
3.3.3. Message Body Length
[...]
If a message is received with both a Transfer-Encoding and a
Content-Length header field, the Transfer-Encoding overrides the
Content-Length. Such a message might indicate an attempt to
perform request smuggling (Section 9.5) or response splitting
(Section 9.4) and ought to be handled as an error. A sender MUST
remove the received Content-Length field prior to forwarding such
a message downstream.
x-ref:
stricter request header parsing
https://redmine.lighttpd.net/issues/2985
Diffstat (limited to 'src/request.c')
-rw-r--r-- | src/request.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/request.c b/src/request.c index 64b2ba45..7ce30869 100644 --- a/src/request.c +++ b/src/request.c @@ -887,9 +887,25 @@ int http_request_parse(server *srv, connection *con, buffer *hdrs) { * which must not be blindly forwarded to backends */ http_header_request_unset(con, HTTP_HEADER_TRANSFER_ENCODING, CONST_STR_LEN("Transfer-Encoding")); - /*(note: ignore whether or not Content-Length was provided)*/ if (con->request.htags & HTTP_HEADER_CONTENT_LENGTH) { - http_header_request_unset(con, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length")); + /* RFC7230 Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing + * 3.3.3. Message Body Length + * [...] + * If a message is received with both a Transfer-Encoding and a + * Content-Length header field, the Transfer-Encoding overrides the + * Content-Length. Such a message might indicate an attempt to + * perform request smuggling (Section 9.5) or response splitting + * (Section 9.4) and ought to be handled as an error. A sender MUST + * remove the received Content-Length field prior to forwarding such + * a message downstream. + */ + if (http_header_strict) { + return http_request_header_line_invalid(srv, 400, "invalid Transfer-Encoding + Content-Length -> 400"); + } + else { + /* ignore Content-Length */ + http_header_request_unset(con, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length")); + } } state.con_length_set = 1; |