summaryrefslogtreecommitdiffstats
path: root/usr.sbin/httpd
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2017-02-07 12:22:41 +0000
committerreyk <reyk@openbsd.org>2017-02-07 12:22:41 +0000
commit619eca925b2d0ff27f9bf4e3b3ac19bd89a172ed (patch)
treebf9a60fbbf27603dbe5d3b94a1e577f16b0d5ff7 /usr.sbin/httpd
parentFix Xr: syspatch(1) -> syspatch(8) (diff)
downloadwireguard-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.c26
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.