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:
parent
2260e0ebe6
commit
abd846c374
@ -28,7 +28,7 @@
|
||||
bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname);
|
||||
CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, bool);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_URLAPI_INT_H */
|
||||
|
||||
13
lib/urlapi.c
13
lib/urlapi.c
@ -497,7 +497,8 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
|
||||
return result;
|
||||
}
|
||||
|
||||
UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
|
||||
UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
|
||||
bool has_scheme)
|
||||
{
|
||||
char *portptr = NULL;
|
||||
char endbracket;
|
||||
@ -542,10 +543,14 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
|
||||
|
||||
/* Browser behavior adaptation. If there's a colon with no digits after,
|
||||
just cut off the name there which makes us ignore the colon and just
|
||||
use the default port. Firefox, Chrome and Safari all do that. */
|
||||
use the default port. Firefox, Chrome and Safari all do that.
|
||||
|
||||
Don't do it if the URL has no scheme, to make something that looks like
|
||||
a scheme not work!
|
||||
*/
|
||||
if(!portptr[1]) {
|
||||
*portptr = '\0';
|
||||
return CURLUE_OK;
|
||||
return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER;
|
||||
}
|
||||
|
||||
if(!ISDIGIT(portptr[1]))
|
||||
@ -904,7 +909,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_parse_port(u, hostname);
|
||||
result = Curl_parse_port(u, hostname, url_has_scheme);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ none
|
||||
unittest
|
||||
</features>
|
||||
<name>
|
||||
urlapi
|
||||
urlapi port number parsing
|
||||
</name>
|
||||
</client>
|
||||
</testcase>
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user