urlapi: don't accept blank port number field without scheme

... as it makes the URL parser accept "very-long-hostname://" as a valid
host name and we don't want that. The parser now only accepts a blank
(no digits) after the colon if the URL starts with a scheme.

Reported-by: d4d on hackerone

Closes #6283
This commit is contained in:
Daniel Stenberg 2020-12-04 17:27:57 +01:00
parent 2260e0ebe6
commit abd846c374
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 39 additions and 18 deletions

View file

@ -14,7 +14,7 @@ none
unittest
</features>
<name>
urlapi
urlapi port number parsing
</name>
</client>
</testcase>

View file

@ -55,7 +55,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15]");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
ret = curl_url_get(u, CURLUPART_PORT, &portnum, CURLU_NO_DEFAULT_PORT);
fail_unless(ret != CURLUE_OK, "curl_url_get portnum returned something");
@ -69,7 +69,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15|");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@ -80,7 +80,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff;fea7:da15]:80");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@ -92,7 +92,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15%25eth3]:80");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0);
fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error");
@ -108,7 +108,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15%25eth3]");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@ -120,7 +120,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15]:81");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0);
fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error");
@ -136,7 +136,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15];81");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@ -147,19 +147,20 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15]80");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
/* Valid IPv6 with no port after the colon, should use default */
/* Valid IPv6 with no port after the colon, should use default if a scheme
was used in the URL */
u = curl_url();
if(!u)
goto fail;
ipv6port = strdup("[fe80::250:56ff:fea7:da15]:");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, TRUE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@ -171,7 +172,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15!25eth3]:80");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port returned non-error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@ -183,10 +184,25 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15%eth3]:80");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port);
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
/* No scheme and no digits following the colon - not accepted. Because that
makes (a*50):// that looks like a scheme be an acceptable input. */
u = curl_url();
if(!u)
goto fail;
ipv6port = strdup("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaa:");
if(!ipv6port)
goto fail;
ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_BAD_PORT_NUMBER, "Curl_parse_port did wrong");
fail:
free(ipv6port);
curl_url_cleanup(u);
}
UNITTEST_STOP