137 lines
4.3 KiB
Diff
137 lines
4.3 KiB
Diff
From 53bcf55b4538067e6dc36242168866becb987bb7 Mon Sep 17 00:00:00 2001
|
|
From: Daniel Stenberg <daniel@haxx.se>
|
|
Date: Wed, 12 Oct 2022 10:47:59 +0200
|
|
Subject: [PATCH] url: use IDN decoded names for HSTS checks
|
|
|
|
Reported-by: Hiroki Kurosawa
|
|
|
|
Closes #9791
|
|
|
|
CVE: CVE-2022-42916
|
|
Upstream-Status: Backport [https://github.com/curl/curl/commit/53bcf55b4538067e6dc36242168866becb987bb7]
|
|
Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
|
|
Comments: Refreshed hunk
|
|
---
|
|
lib/url.c | 91 ++++++++++++++++++++++++++++---------------------------
|
|
1 file changed, 47 insertions(+), 44 deletions(-)
|
|
|
|
diff --git a/lib/url.c b/lib/url.c
|
|
index a3be56bced9de..690c53c81a3c1 100644
|
|
--- a/lib/url.c
|
|
+++ b/lib/url.c
|
|
@@ -2012,10 +2012,56 @@
|
|
if(!strcasecompare("file", data->state.up.scheme))
|
|
return CURLE_OUT_OF_MEMORY;
|
|
}
|
|
+ hostname = data->state.up.hostname;
|
|
+
|
|
+ if(hostname && hostname[0] == '[') {
|
|
+ /* This looks like an IPv6 address literal. See if there is an address
|
|
+ scope. */
|
|
+ size_t hlen;
|
|
+ conn->bits.ipv6_ip = TRUE;
|
|
+ /* cut off the brackets! */
|
|
+ hostname++;
|
|
+ hlen = strlen(hostname);
|
|
+ hostname[hlen - 1] = 0;
|
|
+
|
|
+ zonefrom_url(uh, data, conn);
|
|
+ }
|
|
+
|
|
+ /* make sure the connect struct gets its own copy of the host name */
|
|
+ conn->host.rawalloc = strdup(hostname ? hostname : "");
|
|
+ if(!conn->host.rawalloc)
|
|
+ return CURLE_OUT_OF_MEMORY;
|
|
+ conn->host.name = conn->host.rawalloc;
|
|
+
|
|
+ /*************************************************************
|
|
+ * IDN-convert the hostnames
|
|
+ *************************************************************/
|
|
+ result = Curl_idnconvert_hostname(data, &conn->host);
|
|
+ if(result)
|
|
+ return result;
|
|
+ if(conn->bits.conn_to_host) {
|
|
+ result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
|
|
+ if(result)
|
|
+ return result;
|
|
+ }
|
|
+#ifndef CURL_DISABLE_PROXY
|
|
+ if(conn->bits.httpproxy) {
|
|
+ result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
|
|
+ if(result)
|
|
+ return result;
|
|
+ }
|
|
+ if(conn->bits.socksproxy) {
|
|
+ result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
|
|
+ if(result)
|
|
+ return result;
|
|
+ }
|
|
+#endif
|
|
|
|
#ifndef CURL_DISABLE_HSTS
|
|
+ /* HSTS upgrade */
|
|
if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
|
|
- if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) {
|
|
+ /* This MUST use the IDN decoded name */
|
|
+ if(Curl_hsts(data->hsts, conn->host.name, TRUE)) {
|
|
char *url;
|
|
Curl_safefree(data->state.up.scheme);
|
|
uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
|
|
@@ -2145,26 +2191,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
|
|
|
(void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
|
|
|
|
- hostname = data->state.up.hostname;
|
|
- if(hostname && hostname[0] == '[') {
|
|
- /* This looks like an IPv6 address literal. See if there is an address
|
|
- scope. */
|
|
- size_t hlen;
|
|
- conn->bits.ipv6_ip = TRUE;
|
|
- /* cut off the brackets! */
|
|
- hostname++;
|
|
- hlen = strlen(hostname);
|
|
- hostname[hlen - 1] = 0;
|
|
-
|
|
- zonefrom_url(uh, data, conn);
|
|
- }
|
|
-
|
|
- /* make sure the connect struct gets its own copy of the host name */
|
|
- conn->host.rawalloc = strdup(hostname ? hostname : "");
|
|
- if(!conn->host.rawalloc)
|
|
- return CURLE_OUT_OF_MEMORY;
|
|
- conn->host.name = conn->host.rawalloc;
|
|
-
|
|
#ifdef ENABLE_IPV6
|
|
if(data->set.scope_id)
|
|
/* Override any scope that was set above. */
|
|
@@ -3713,29 +3739,6 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|
if(result)
|
|
goto out;
|
|
|
|
- /*************************************************************
|
|
- * IDN-convert the hostnames
|
|
- *************************************************************/
|
|
- result = Curl_idnconvert_hostname(data, &conn->host);
|
|
- if(result)
|
|
- goto out;
|
|
- if(conn->bits.conn_to_host) {
|
|
- result = Curl_idnconvert_hostname(data, &conn->conn_to_host);
|
|
- if(result)
|
|
- goto out;
|
|
- }
|
|
-#ifndef CURL_DISABLE_PROXY
|
|
- if(conn->bits.httpproxy) {
|
|
- result = Curl_idnconvert_hostname(data, &conn->http_proxy.host);
|
|
- if(result)
|
|
- goto out;
|
|
- }
|
|
- if(conn->bits.socksproxy) {
|
|
- result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host);
|
|
- if(result)
|
|
- goto out;
|
|
- }
|
|
-#endif
|
|
|
|
/*************************************************************
|
|
* Check whether the host and the "connect to host" are equal.
|