diff options
author | reyk <reyk@openbsd.org> | 2017-02-07 12:22:41 +0000 |
---|---|---|
committer | reyk <reyk@openbsd.org> | 2017-02-07 12:22:41 +0000 |
commit | 619eca925b2d0ff27f9bf4e3b3ac19bd89a172ed (patch) | |
tree | bf9a60fbbf27603dbe5d3b94a1e577f16b0d5ff7 /usr.sbin/httpd | |
parent | Fix Xr: syspatch(1) -> syspatch(8) (diff) | |
download | wireguard-openbsd-619eca925b2d0ff27f9bf4e3b3ac19bd89a172ed.tar.xz wireguard-openbsd-619eca925b2d0ff27f9bf4e3b3ac19bd89a172ed.zip |
Improve parsing of the HTTP request line
Make sure that the beginning of a new request starts with an
alphabetic character. This is a quick way to detect non-ASCII
requests (eg. TLS on port 80). The full validation of the request
method is done once the input line is read.
Make sure that non-terminated lines do not exceed the
SERVER_MAXHEADERLENGTH which is 8k. As the current read watermark is
set to 64k, this means that the limit check is triggered after max.
64k of input, depending on the TCP read buffer.
OK benno@ jsing@
Diffstat (limited to 'usr.sbin/httpd')
-rw-r--r-- | usr.sbin/httpd/server_http.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c index 7615cad70cb..56409bffd5b 100644 --- a/usr.sbin/httpd/server_http.c +++ b/usr.sbin/httpd/server_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_http.c,v 1.113 2017/02/02 22:19:59 reyk Exp $ */ +/* $OpenBSD: server_http.c,v 1.114 2017/02/07 12:22:41 reyk Exp $ */ /* * Copyright (c) 2006 - 2017 Reyk Floeter <reyk@openbsd.org> @@ -216,9 +216,27 @@ server_read_http(struct bufferevent *bev, void *arg) goto done; } - while (!clt->clt_headersdone && (line = - evbuffer_readln(src, NULL, EVBUFFER_EOL_CRLF_STRICT)) != NULL) { - linelen = strlen(line); + while (!clt->clt_headersdone) { + if (!clt->clt_line) { + /* Peek into the buffer to see if it looks like HTTP */ + key = EVBUFFER_DATA(src); + if (!isalpha(*key)) { + server_abort_http(clt, 400, + "invalid request line"); + goto abort; + } + } + + if ((line = evbuffer_readln(src, + &linelen, EVBUFFER_EOL_CRLF_STRICT)) == NULL) { + /* No newline found after too many bytes */ + if (size > SERVER_MAXHEADERLENGTH) { + server_abort_http(clt, 413, + "request line too long"); + goto abort; + } + break; + } /* * An empty line indicates the end of the request. |