fix CVE-2022-22576 CVE-2022-27774 CVE-2022-27775 CVE-2022-27776

This commit is contained in:
eaglegai 2022-05-06 20:08:56 +08:00
parent e74e02b3cb
commit 08763adb5c
7 changed files with 462 additions and 1 deletions

View File

@ -0,0 +1,69 @@
From 2b4afd8dd2132a0edd16acbe7c8d4d5c4fd06e61 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 19 Apr 2022 12:49:28 +0200
Subject: [PATCH 2/3] transfer: redirects to other protocols or ports clear
auth
... unless explicitly permitted.
Bug: https://curl.se/docs/CVE-2022-27774.html
Reported-by: Harry Sintonen
diff --git a/lib/transfer.c b/lib/transfer.c
index b8c3bcb..967ac03 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1645,10 +1645,53 @@ CURLcode Curl_follow(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
else {
-
uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0);
if(uc)
return Curl_uc_to_curlcode(uc);
+
+ /* Clear auth if this redirects to a different port number or protocol,
+ unless permitted */
+ if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) {
+ char *portnum;
+ int port;
+ bool clear = FALSE;
+
+ uc = curl_url_get(data->state.uh, CURLUPART_PORT, &portnum,
+ CURLU_DEFAULT_PORT);
+ if(uc) {
+ free(newurl);
+ return Curl_uc_to_curlcode(uc);
+ }
+ port = atoi(portnum);
+ free(portnum);
+
+ if(port != data->info.conn_remote_port) {
+ infof(data, "Clear auth, redirects to port from %u to %u",
+ data->info.conn_remote_port, port);
+ clear = TRUE;
+ }
+ else {
+ char *scheme;
+ const struct Curl_handler *p;
+ uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0);
+ if(uc) {
+ free(newurl);
+ return Curl_uc_to_curlcode(uc);
+ }
+
+ p = Curl_builtin_scheme(scheme);
+ if(p && (p->protocol != data->info.conn_protocol)) {
+ infof(data, "Clear auth, redirects scheme from %s to %s",
+ data->info.conn_scheme, scheme);
+ clear = TRUE;
+ }
+ free(scheme);
+ }
+ if(clear) {
+ Curl_safefree(data->set.str[STRING_USERNAME]);
+ Curl_safefree(data->set.str[STRING_PASSWORD]);
+ }
+ }
}
if(type == FOLLOW_FAKE) {

View File

@ -0,0 +1,80 @@
From 139a54ed0a172adaaf1a78d6f4fff50b2c3f9e08 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Apr 2022 17:59:15 +0200
Subject: [PATCH] openssl: don't leak the SRP credentials in redirects either
Follow-up to 620ea21410030
Reported-by: Harry Sintonen
Closes #8751
---
lib/http.c | 10 +++++-----
lib/http.h | 6 ++++++
lib/vtls/openssl.c | 3 ++-
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/lib/http.c b/lib/http.c
index f0476f3b9272..0d5c449bc72a 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -776,10 +776,10 @@ output_auth_headers(struct Curl_easy *data,
}
/*
- * allow_auth_to_host() tells if autentication, cookies or other "sensitive
- * data" can (still) be sent to this host.
+ * Curl_allow_auth_to_host() tells if authentication, cookies or other
+ * "sensitive data" can (still) be sent to this host.
*/
-static bool allow_auth_to_host(struct Curl_easy *data)
+bool Curl_allow_auth_to_host(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
return (!data->state.this_is_a_follow ||
@@ -864,7 +864,7 @@ Curl_http_output_auth(struct Curl_easy *data,
/* To prevent the user+password to get sent to other than the original host
due to a location-follow */
- if(allow_auth_to_host(data)
+ if(Curl_allow_auth_to_host(data)
|| conn->bits.netrc
)
result = output_auth_headers(conn, authhost, request, path, FALSE);
@@ -1917,7 +1917,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
checkprefix("Cookie:", compare)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
- !allow_auth_to_host(data))
+ !Curl_allow_auth_to_host(data))
;
else {
result = Curl_dyn_addf(req, "%s\r\n", compare);
diff --git a/lib/http.h b/lib/http.h
index 0972261e63bd..c4ab3c22dec9 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -364,4 +364,10 @@ Curl_http_output_auth(struct Curl_easy *data,
bool proxytunnel); /* TRUE if this is the request setting
up the proxy tunnel */
+/*
+ * Curl_allow_auth_to_host() tells if authentication, cookies or other
+ * "sensitive data" can (still) be sent to this host.
+ */
+bool Curl_allow_auth_to_host(struct Curl_easy *data);
+
#endif /* HEADER_CURL_HTTP_H */
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 5d8e2d39d8e2..3722005d44e9 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -2924,7 +2924,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#endif
#ifdef USE_TLS_SRP
- if(ssl_authtype == CURL_TLSAUTH_SRP) {
+ if((ssl_authtype == CURL_TLSAUTH_SRP) &&
+ Curl_allow_auth_to_host(data)) {
char * const ssl_username = SSL_SET_OPTION(username);
infof(data, "Using TLS-SRP username: %s\n", ssl_username);

View File

@ -0,0 +1,129 @@
From e193f712be95dc9e5e2b92eae6381d4572231152 Mon Sep 17 00:00:00 2001
From: Patrick Monnerat <patrick@monnerat.net>
Date: Sun, 17 Apr 2022 23:29:46 +0200
Subject: [PATCH] url: check sasl additional parameters for connection reuse.
Also move static function safecmp() as non-static Curl_safecmp() since
its purpose is needed at several places.
Bug: https://curl.se/docs/CVE-2022-22576.html
CVE-2022-22576
diff --git a/lib/strcase.c b/lib/strcase.c
index 955e3c7..cd04f2c 100644
--- a/lib/strcase.c
+++ b/lib/strcase.c
@@ -251,6 +251,16 @@ void Curl_strntolower(char *dest, const char *src, size_t n)
} while(*src++ && --n);
}
+/* Compare case-sensitive NUL-terminated strings, taking care of possible
+ * null pointers. Return true if arguments match.
+ */
+bool Curl_safecmp(char *a, char *b)
+{
+ if(a && b)
+ return !strcmp(a, b);
+ return !a && !b;
+}
+
/* --- public functions --- */
int curl_strequal(const char *first, const char *second)
diff --git a/lib/strcase.h b/lib/strcase.h
index 10dc698..127bfdd 100644
--- a/lib/strcase.h
+++ b/lib/strcase.h
@@ -48,4 +48,6 @@ char Curl_raw_toupper(char in);
void Curl_strntoupper(char *dest, const char *src, size_t n);
void Curl_strntolower(char *dest, const char *src, size_t n);
+bool Curl_safecmp(char *a, char *b);
+
#endif /* HEADER_CURL_STRCASE_H */
diff --git a/lib/url.c b/lib/url.c
index a6519be..a8e2e41 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -752,6 +752,7 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->passwd);
Curl_safefree(conn->sasl_authzid);
Curl_safefree(conn->options);
+ Curl_safefree(conn->oauth_bearer);
Curl_dyn_free(&conn->trailer);
Curl_safefree(conn->host.rawalloc); /* host name buffer */
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
@@ -1284,7 +1285,9 @@ ConnectionExists(struct Curl_easy *data,
/* This protocol requires credentials per connection,
so verify that we're using the same name and password as well */
if(strcmp(needle->user, check->user) ||
- strcmp(needle->passwd, check->passwd)) {
+ strcmp(needle->passwd, check->passwd) ||
+ !Curl_safecmp(needle->sasl_authzid, check->sasl_authzid) ||
+ !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) {
/* one of them was different */
continue;
}
@@ -3486,6 +3489,14 @@ static CURLcode create_conn(struct Curl_easy *data,
}
}
+ if(data->set.str[STRING_BEARER]) {
+ conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
+ if(!conn->oauth_bearer) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ }
+
#ifdef USE_UNIX_SOCKETS
if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
diff --git a/lib/urldata.h b/lib/urldata.h
index abd8110..11d7a33 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -967,6 +967,7 @@ struct connectdata {
char *options; /* options string, allocated */
char *sasl_authzid; /* authorisation identity string, allocated */
+ char *oauth_bearer; /* OAUTH2 bearer, allocated */
int httpversion; /* the HTTP version*10 reported by the server */
int rtspversion; /* the RTSP version*10 reported by the server */
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 62239be..c074605 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -121,14 +121,6 @@ static bool blobcmp(struct curl_blob *first, struct curl_blob *second)
return !memcmp(first->data, second->data, first->len); /* same data */
}
-static bool safecmp(char *a, char *b)
-{
- if(a && b)
- return !strcmp(a, b);
- else if(!a && !b)
- return TRUE; /* match */
- return FALSE; /* no match */
-}
bool
Curl_ssl_config_matches(struct ssl_primary_config *data,
@@ -142,11 +133,11 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
(data->verifystatus == needle->verifystatus) &&
blobcmp(data->cert_blob, needle->cert_blob) &&
blobcmp(data->issuercert_blob, needle->issuercert_blob) &&
- safecmp(data->CApath, needle->CApath) &&
- safecmp(data->CAfile, needle->CAfile) &&
- safecmp(data->clientcert, needle->clientcert) &&
- safecmp(data->random_file, needle->random_file) &&
- safecmp(data->egdsocket, needle->egdsocket) &&
+ Curl_safecmp(data->CApath, needle->CApath) &&
+ Curl_safecmp(data->CAfile, needle->CAfile) &&
+ Curl_safecmp(data->clientcert, needle->clientcert) &&
+ Curl_safecmp(data->random_file, needle->random_file) &&
+ Curl_safecmp(data->egdsocket, needle->egdsocket) &&
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))

View File

@ -0,0 +1,33 @@
From 46091487fbdb37ffbe9c495de86c62d14634b71a Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 21 Apr 2022 12:30:34 +0200
Subject: [PATCH] conncache: include the zone id in the "bundle" hashkey
Make connections to two separate IPv6 zone ids create separate
connections.
Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2022-27775.html
---
lib/conncache.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
Index: curl-7.74.0/lib/conncache.c
===================================================================
--- curl-7.74.0.orig/lib/conncache.c
+++ curl-7.74.0/lib/conncache.c
@@ -159,8 +159,12 @@ static void hashkey(struct connectdata *
/* report back which name we used */
*hostp = hostname;
- /* put the number first so that the hostname gets cut off if too long */
- msnprintf(buf, len, "%ld%s", port, hostname);
+ /* put the numbers first so that the hostname gets cut off if too long */
+#ifdef ENABLE_IPV6
+ msnprintf(buf, len, "%u/%ld/%s", conn->scope_id, port, hostname);
+#else
+ msnprintf(buf, len, "%ld/%s", port, hostname);
+#endif
}
/* Returns number of connections currently held in the connection cache.

View File

@ -0,0 +1,103 @@
From 125302094326ad5eb0ea87f2d2ece6ceab1b1e59 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 22 Apr 2022 08:19:18 +0200
Subject: [PATCH] http: avoid auth/cookie on redirects same host diff port
CVE-2022-27776
Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2022-27776.html
diff --git a/lib/http.c b/lib/http.c
index c232ed4..7ccc5b5 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -751,6 +751,21 @@ output_auth_headers(struct connectdata *conn,
return CURLE_OK;
}
+/*
+ * allow_auth_to_host() tells if autentication, cookies or other "sensitive
+ * data" can (still) be sent to this host.
+ */
+static bool allow_auth_to_host(struct Curl_easy *data)
+{
+ struct connectdata *conn = data->conn;
+ return (!data->state.this_is_a_follow ||
+ data->set.allow_auth_to_other_hosts ||
+ (data->state.first_host &&
+ strcasecompare(data->state.first_host, conn->host.name) &&
+ (data->state.first_remote_port == conn->remote_port) &&
+ (data->state.first_remote_protocol == conn->handler->protocol)));
+}
+
/**
* Curl_http_output_auth() setups the authentication headers for the
* host/proxy and the correct authentication
@@ -822,15 +837,12 @@ Curl_http_output_auth(struct connectdata *conn,
with it */
authproxy->done = TRUE;
- /* To prevent the user+password to get sent to other than the original
- host due to a location-follow, we do some weirdo checks here */
- if(!data->state.this_is_a_follow ||
- conn->bits.netrc ||
- !data->state.first_host ||
- data->set.allow_auth_to_other_hosts ||
- strcasecompare(data->state.first_host, conn->host.name)) {
+ /* To prevent the user+password to get sent to other than the original host
+ due to a location-follow */
+ if(allow_auth_to_host(data)
+ || conn->bits.netrc
+ )
result = output_auth_headers(conn, authhost, request, path, FALSE);
- }
else
authhost->done = TRUE;
@@ -1802,10 +1814,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
checkprefix("Cookie:", compare)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
- (data->state.this_is_a_follow &&
- data->state.first_host &&
- !data->set.allow_auth_to_other_hosts &&
- !strcasecompare(data->state.first_host, conn->host.name)))
+ !allow_auth_to_host(data))
;
else {
result = Curl_dyn_addf(req, "%s\r\n", compare);
@@ -1989,6 +1998,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return CURLE_OUT_OF_MEMORY;
data->state.first_remote_port = conn->remote_port;
+ data->state.first_remote_protocol = conn->handler->protocol;
}
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
diff --git a/lib/urldata.h b/lib/urldata.h
index a71ce08..4f434f3 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1332,13 +1332,15 @@ struct UrlState {
char *ulbuf; /* allocated upload buffer or NULL */
curl_off_t current_speed; /* the ProgressShow() function sets this,
bytes / second */
- char *first_host; /* host name of the first (not followed) request.
- if set, this should be the host name that we will
- sent authorization to, no else. Used to make Location:
- following not keep sending user+password... This is
- strdup() data.
- */
- int first_remote_port; /* remote port of the first (not followed) request */
+
+ /* host name, port number and protocol of the first (not followed) request.
+ if set, this should be the host name that we will sent authorization to,
+ no else. Used to make Location: following not keep sending user+password.
+ This is strdup()ed data. */
+ char *first_host;
+ int first_remote_port;
+ unsigned int first_remote_protocol;
+
struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
long sessionage; /* number of the most recent session */
unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */

View File

@ -0,0 +1,35 @@
From b92ebe53f3fc7b4a4355724a22690fdef4f1bf2f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 19 Apr 2022 12:49:28 +0200
Subject: [PATCH 1/3] connect: store "conn_remote_port" in the info struct
To make it available after the connection ended.
diff --git a/lib/connect.c b/lib/connect.c
index e65d24d..0f122ce 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -611,6 +611,7 @@ void Curl_persistconninfo(struct connectdata *conn)
conn->data->info.conn_scheme = conn->handler->scheme;
conn->data->info.conn_protocol = conn->handler->protocol;
conn->data->info.conn_primary_port = conn->primary_port;
+ conn->data->info.conn_remote_port = conn->remote_port;
conn->data->info.conn_local_port = conn->local_port;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 11d7a33..a71ce08 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1145,7 +1145,11 @@ struct PureInfo {
reused, in the connection cache. */
char conn_primary_ip[MAX_IPADR_LEN];
- long conn_primary_port;
+ int conn_primary_port; /* this is the destination port to the connection,
+ which might have been a proxy */
+ int conn_remote_port; /* this is the "remote port", which is the port
+ number of the used URL, independent of proxy or
+ not */
char conn_local_ip[MAX_IPADR_LEN];
long conn_local_port;
const char *conn_scheme;

View File

@ -6,7 +6,7 @@
Name: curl
Version: 7.71.1
Release: 12
Release: 13
Summary: Curl is used in command lines or scripts to transfer data
License: MIT
URL: https://curl.haxx.se/
@ -33,6 +33,12 @@ Patch119: backport-CVE-2021-22945.patch
Patch120: backport-0001-CVE-2021-22946.patch
Patch121: backport-0002-CVE-2021-22946.patch
Patch122: backport-CVE-2021-22947.patch
Patch123: backport-CVE-2022-22576.patch
Patch124: backport-CVE-2022-27775.patch
Patch125: backport-CVE-2022-27776.patch
Patch126: backport-pre-CVE-2022-27774.patch
Patch127: backport-001-CVE-2022-27774.patch
Patch128: backport-002-CVE-2022-27774.patch
BuildRequires: automake brotli-devel coreutils gcc groff krb5-devel
BuildRequires: libidn2-devel libnghttp2-devel libpsl-devel
@ -174,6 +180,12 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
%{_mandir}/man3/*
%changelog
* Fri May 06 2022 gaihuiying <eaglegai@163.com> - 7.71.1-13
- Type:cves
- CVE:CVE-2022-22576 CVE-2022-27774 CVE-2022-27775 CVE-2022-27776
- SUG:NA
- DESC:fix CVE-2022-22576 CVE-2022-27774 CVE-2022-27775 CVE-2022-27776
* Thu Jan 20 2021 gaoxingwang<gaoxingwang@huawei.com> - 7.71.1-12
- Type:CVE
- CVE:CVE-2021-22922 CVE-2021-22923