1From 53bcf55b4538067e6dc36242168866becb987bb7 Mon Sep 17 00:00:00 2001 2From: Daniel Stenberg <daniel@haxx.se> 3Date: Wed, 12 Oct 2022 10:47:59 +0200 4Subject: [PATCH] url: use IDN decoded names for HSTS checks 5 6Reported-by: Hiroki Kurosawa 7 8Closes #9791 9 10CVE: CVE-2022-42916 11Upstream-Status: Backport [https://github.com/curl/curl/commit/53bcf55b4538067e6dc36242168866becb987bb7] 12Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com> 13Comments: Refreshed hunk 14--- 15 lib/url.c | 91 ++++++++++++++++++++++++++++--------------------------- 16 1 file changed, 47 insertions(+), 44 deletions(-) 17 18diff --git a/lib/url.c b/lib/url.c 19index a3be56bced9de..690c53c81a3c1 100644 20--- a/lib/url.c 21+++ b/lib/url.c 22@@ -2012,10 +2012,56 @@ 23 if(!strcasecompare("file", data->state.up.scheme)) 24 return CURLE_OUT_OF_MEMORY; 25 } 26+ hostname = data->state.up.hostname; 27+ 28+ if(hostname && hostname[0] == '[') { 29+ /* This looks like an IPv6 address literal. See if there is an address 30+ scope. */ 31+ size_t hlen; 32+ conn->bits.ipv6_ip = TRUE; 33+ /* cut off the brackets! */ 34+ hostname++; 35+ hlen = strlen(hostname); 36+ hostname[hlen - 1] = 0; 37+ 38+ zonefrom_url(uh, data, conn); 39+ } 40+ 41+ /* make sure the connect struct gets its own copy of the host name */ 42+ conn->host.rawalloc = strdup(hostname ? hostname : ""); 43+ if(!conn->host.rawalloc) 44+ return CURLE_OUT_OF_MEMORY; 45+ conn->host.name = conn->host.rawalloc; 46+ 47+ /************************************************************* 48+ * IDN-convert the hostnames 49+ *************************************************************/ 50+ result = Curl_idnconvert_hostname(data, &conn->host); 51+ if(result) 52+ return result; 53+ if(conn->bits.conn_to_host) { 54+ result = Curl_idnconvert_hostname(data, &conn->conn_to_host); 55+ if(result) 56+ return result; 57+ } 58+#ifndef CURL_DISABLE_PROXY 59+ if(conn->bits.httpproxy) { 60+ result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); 61+ if(result) 62+ return result; 63+ } 64+ if(conn->bits.socksproxy) { 65+ result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); 66+ if(result) 67+ return result; 68+ } 69+#endif 70 71 #ifndef CURL_DISABLE_HSTS 72+ /* HSTS upgrade */ 73 if(data->hsts && strcasecompare("http", data->state.up.scheme)) { 74- if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) { 75+ /* This MUST use the IDN decoded name */ 76+ if(Curl_hsts(data->hsts, conn->host.name, TRUE)) { 77 char *url; 78 Curl_safefree(data->state.up.scheme); 79 uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0); 80@@ -2145,26 +2191,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, 81 82 (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); 83 84- hostname = data->state.up.hostname; 85- if(hostname && hostname[0] == '[') { 86- /* This looks like an IPv6 address literal. See if there is an address 87- scope. */ 88- size_t hlen; 89- conn->bits.ipv6_ip = TRUE; 90- /* cut off the brackets! */ 91- hostname++; 92- hlen = strlen(hostname); 93- hostname[hlen - 1] = 0; 94- 95- zonefrom_url(uh, data, conn); 96- } 97- 98- /* make sure the connect struct gets its own copy of the host name */ 99- conn->host.rawalloc = strdup(hostname ? hostname : ""); 100- if(!conn->host.rawalloc) 101- return CURLE_OUT_OF_MEMORY; 102- conn->host.name = conn->host.rawalloc; 103- 104 #ifdef ENABLE_IPV6 105 if(data->set.scope_id) 106 /* Override any scope that was set above. */ 107@@ -3713,29 +3739,6 @@ static CURLcode create_conn(struct Curl_easy *data, 108 if(result) 109 goto out; 110 111- /************************************************************* 112- * IDN-convert the hostnames 113- *************************************************************/ 114- result = Curl_idnconvert_hostname(data, &conn->host); 115- if(result) 116- goto out; 117- if(conn->bits.conn_to_host) { 118- result = Curl_idnconvert_hostname(data, &conn->conn_to_host); 119- if(result) 120- goto out; 121- } 122-#ifndef CURL_DISABLE_PROXY 123- if(conn->bits.httpproxy) { 124- result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); 125- if(result) 126- goto out; 127- } 128- if(conn->bits.socksproxy) { 129- result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); 130- if(result) 131- goto out; 132- } 133-#endif 134 135 /************************************************************* 136 * Check whether the host and the "connect to host" are equal. 137