summaryrefslogtreecommitdiff
path: root/src/request.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2019-10-06 15:14:05 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2020-01-26 00:41:04 -0500
commit66624b375b6f1ceae446ba09d55f123683506337 (patch)
treedaa1164dd120c1805746ff6ff2d15a0db83f990e /src/request.c
parent61f85d14ee4444755e0771495b97af11162448dd (diff)
downloadlighttpd-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.c20
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;