urlapi: deny hostnames with more than one trailing dot
No binary (build failed)
—
(log yok)
| @@ -475,6 +475,13 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname, | |
| if(hlen != len) | |
| /* hostname with bad content */ | |
| return CURLUE_BAD_HOSTNAME; | |
| + | else if((hlen >= 2) && |
| + | (hostname[hlen - 1] == '.') && (hostname[hlen - 2] == '.')) |
| + | /* more than one trailing dot is not allowed */ |
| + | return CURLUE_BAD_HOSTNAME; |
| + | else if((hlen == 1) && (hostname[0] == '.')) |
| + | /* just a single dot is not allowed */ |
| + | return CURLUE_BAD_HOSTNAME; |
| } | |
| return CURLUE_OK; | |
| } | |
| @@ -127,7 +127,7 @@ class TestSSLUse: | |
| # the SNI the server received is without trailing dot | |
| assert r.json['SSL_TLS_SNI'] == env.domain1, f'{r.json}' | |
| - | # use hostname with double trailing dot, verify handshake |
| + | # use hostname with double trailing dot |
| @pytest.mark.parametrize("proto", Env.http_protos()) | |
| def test_17_04_double_dot(self, env: Env, proto, httpd, nghttpx): | |
| curl = CurlClient(env=env) | |
| @@ -142,10 +142,8 @@ class TestSSLUse: | |
| if proto != 'h3': # we proxy h3 | |
| assert r.json['SSL_TLS_SNI'] == env.domain1, f'{r.json}' | |
| assert False, f'should not have succeeded: {r.json}' | |
| - | # 7 - Rustls rejects a servername with .. during setup |
| - | # 35 - LibreSSL rejects setting an SNI name with trailing dot |
| - | # 60 - peer name matching failed against certificate |
| - | assert r.exit_code in [7, 35, 60], f'{r}' |
| + | # 3 - not allowed in the URL |
| + | assert r.exit_code in [3], f'{r}' |
| # use ip address for connect | |
| @pytest.mark.parametrize("proto", Env.http_protos()) | |
| @@ -196,20 +196,19 @@ static const struct testcase get_parts_list[] = { | |
| "http://host:00080/", | |
| "http | [11] | [12] | [13] | host | 80 | / | [16] | [17]", | |
| 0, 0, CURLUE_OK }, | |
| - | { /* Single dot host - technically valid in some contexts but often |
| - | rejected */ |
| + | { /* Single dot host - not ok */ |
| "http://./", | |
| - | "http | [11] | [12] | [13] | . | [15] | / | [16] | [17]", |
| - | 0, 0, CURLUE_OK }, |
| + | "", |
| + | 0, 0, CURLUE_BAD_HOSTNAME }, |
| { /* Host starting with a dash (RFC 1123 technically allows it, but many | |
| parsers don't) */ | |
| "http://-atest/", | |
| "http | [11] | [12] | [13] | -atest | [15] | / | [16] | [17]", | |
| 0, 0, CURLUE_OK }, | |
| - | { /* Multiple trailing dots, not okay in DNS but works in /etc/hosts */ |
| + | { /* Multiple trailing dots is not okey */ |
| "http://example.com../", | |
| - | "http | [11] | [12] | [13] | example.com.. | [15] | / | [16] | [17]", |
| - | 0, 0, CURLUE_OK }, |
| + | "", |
| + | 0, 0, CURLUE_BAD_HOSTNAME }, |
| { /* Empty IPv6 Zone ID */ | |
| "http://[fe80::1%]/", | |
| "", 0, 0, CURLUE_BAD_IPV6 }, | |
| @@ -626,6 +625,13 @@ static const struct testcase get_parts_list[] = { | |
| }; | |
| static const struct urltestcase get_url_list[] = { | |
| + | {"http://hej./", "http://hej./", 0, 0, CURLUE_OK}, |
| + | {"http://hej../", "", 0, 0, CURLUE_BAD_HOSTNAME}, |
| + | {"http://hej.../", "", 0, 0, CURLUE_BAD_HOSTNAME}, |
| + | {"http://hej..../index.html", "", 0, 0, CURLUE_BAD_HOSTNAME}, |
| + | {"http://.", "", 0, 0, CURLUE_BAD_HOSTNAME}, |
| + | {"http://..", "", 0, 0, CURLUE_BAD_HOSTNAME}, |
| + | {"http://...", "", 0, 0, CURLUE_BAD_HOSTNAME}, |
| {"018.0.0.0", "http://018.0.0.0/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | |
| {"08", "http://08/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | |
| {"0", "http://0.0.0.0/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | |