From: Stephan Bosch Date: Thu, 31 Oct 2019 08:07:42 +0000 (+0100) Subject: lib-http: http-url - Fix handling of double slash in request target URL. X-Git-Tag: 2.3.9~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa52ae31cc273847ffe833e9af8d8423b2918f0c;p=thirdparty%2Fdovecot%2Fcore.git lib-http: http-url - Fix handling of double slash in request target URL. A origin-form URL starting with double slash caused the initial path segment to be erroneously recognized as the URL authority, making the path part unexpectedly empty (NULL). This could cause the HTTP server to crash. --- diff --git a/src/lib-http/http-url.c b/src/lib-http/http-url.c index 39526e5e54..78af18babf 100644 --- a/src/lib-http/http-url.c +++ b/src/lib-http/http-url.c @@ -345,7 +345,8 @@ static bool http_url_do_parse(struct http_url_parser *url_parser) * ["//"] authority ; when parsing a request target */ if (parser->cur < parser->end && parser->cur[0] == '/') { - if ((parser->cur + 1) < parser->end && parser->cur[1] == '/') { + if ((have_scheme || !url_parser->request_target) && + (parser->cur + 1) < parser->end && parser->cur[1] == '/') { parser->cur += 2; relative = FALSE; have_authority = TRUE; diff --git a/src/lib-http/test-http-request-parser.c b/src/lib-http/test-http-request-parser.c index 981d123087..414e66b9f3 100644 --- a/src/lib-http/test-http-request-parser.c +++ b/src/lib-http/test-http-request-parser.c @@ -260,6 +260,24 @@ valid_request_parse_tests[] = { }, .version_major = 1, .version_minor = 1, }, + { + .request = + "GET //index.php HTTP/1.1\r\n" + "Date: Sun, 07 Oct 2012 19:52:03 GMT\r\n" + "Host: example.com\r\n" + "Date: Sun, 13 Oct 2013 13:13:13 GMT\r\n" + "\r\n", + .method = "GET", + .target_raw = "//index.php", + .target = { + .format = HTTP_REQUEST_TARGET_FORMAT_ORIGIN, + .url = { + .host = { .name = "example.com" }, + .path = "//index.php", + }, + }, + .version_major = 1, .version_minor = 1, + }, }; static const unsigned int valid_request_parse_test_count = diff --git a/src/lib-http/test-http-url.c b/src/lib-http/test-http-url.c index 64096e269c..a9fdf241e6 100644 --- a/src/lib-http/test-http-url.c +++ b/src/lib-http/test-http-url.c @@ -98,6 +98,88 @@ static struct valid_http_url_test valid_url_tests[] = { .enc_query = "question=What%20are%20you%20doing%3f&answer=Nothing.", }, }, + /* Empty path segments */ + { + .url = "http://target//index.php", + .url_parsed = { + .path = "//index.php", + .host = { .name = "target" }, + }, + }, + { + .url = "http://target//path//index.php", + .url_parsed = { + .path = "//path//index.php", + .host = { .name = "target" }, + }, + }, + { + .url = "http://target//path/", + .url_parsed = { + .path = "//path/", + .host = { .name = "target" }, + }, + }, + { + .url = "http://target//path//", + .url_parsed = { + .path = "//path//", + .host = { .name = "target" }, + }, + }, + { + .url = "http://target//path//to//./index.php", + .url_parsed = { + .path = "//path//to//index.php", + .host = { .name = "target" }, + }, + }, + { + .url = "http://target//path//to//../index.php", + .url_parsed = { + .path = "//path//to/index.php", + .host = { .name = "target" }, + }, + }, + { + .url = "/index.php", + .url_base = { + .host = { .name = "target" }, + }, + .url_parsed = { + .host = { .name = "target" }, + .path = "/index.php", + }, + }, + { + .url = "//index.php", + .url_base = { + .host = { .name = "target" }, + }, + .url_parsed = { + .host = { .name = "index.php" }, + }, + }, + { + .url = "/path/to/index.php", + .url_base = { + .host = { .name = "target" }, + }, + .url_parsed = { + .host = { .name = "target" }, + .path = "/path/to/index.php", + }, + }, + { + .url = "//path//to//index.php", + .url_base = { + .host = { .name = "target" }, + }, + .url_parsed = { + .host = { .name = "path" }, + .path = "//to//index.php", + }, + }, /* These next 2 URLs don't follow the recommendations in http://tools.ietf.org/html/rfc1034#section-3.5 and http://tools.ietf.org/html/rfc3696