From f5147319fe7012f52ac05d1ef2fbb4c6c76b97a9 Mon Sep 17 00:00:00 2001 From: Patrick Monnerat Date: Mon, 25 Apr 2022 11:44:05 +0200 Subject: [PATCH 1/9] 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 Closes #8746 Signed-off-by: zhouhaifeng --- lib/strcase.c | 10 ++++++++++ lib/strcase.h | 2 ++ lib/url.c | 13 ++++++++++++- lib/urldata.h | 1 + lib/vtls/vtls.c | 21 ++++++--------------- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/lib/strcase.c b/lib/strcase.c index 955e3c79e..cd04f2c0b 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 10dc69881..127bfdd44 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 8a2845ddd..b93a921ed 100644 --- a/lib/url.c +++ b/lib/url.c @@ -784,6 +784,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 */ @@ -1332,7 +1333,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; } @@ -3592,6 +3595,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 1d9911208..d3f337638 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -979,6 +979,7 @@ struct connectdata { char *passwd; /* password string, allocated */ char *options; /* options string, allocated */ char *sasl_authzid; /* authorisation identity string, allocated */ + char *oauth_bearer; /* OAUTH2 bearer, allocated */ unsigned char httpversion; /* the HTTP version*10 reported by the server */ struct curltime now; /* "current" time */ struct curltime created; /* creation time */ diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index e5bbe1f5f..4c24348c2 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -125,15 +125,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, @@ -147,12 +138,12 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, blobcmp(data->cert_blob, needle->cert_blob) && blobcmp(data->ca_info_blob, needle->ca_info_blob) && blobcmp(data->issuercert_blob, needle->issuercert_blob) && - safecmp(data->CApath, needle->CApath) && - safecmp(data->CAfile, needle->CAfile) && - safecmp(data->issuercert, needle->issuercert) && - 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->issuercert, needle->issuercert) && + 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->curves, needle->curves) && -- Gitee From 376f7dbfce8e029e01944d8f8e994eb62d80963d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 11:48:00 +0200 Subject: [PATCH 2/9] 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 Closes #8747 Signed-off-by: zhouhaifeng --- lib/conncache.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/conncache.c b/lib/conncache.c index f5ba8ff70..67d3943b8 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -160,8 +160,12 @@ static void hashkey(struct connectdata *conn, char *buf, /* 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 Curl_strntolower(buf, buf, len); } -- Gitee From e87ef02d08db2541ae56276e8202e1d57540d1f8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 13:05:40 +0200 Subject: [PATCH 3/9] 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 Closes #8749 Signed-off-by: zhouhaifeng --- lib/http.c | 34 ++++++++++++++++++++++------------ lib/urldata.h | 16 +++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/lib/http.c b/lib/http.c index 05b971b20..180edaf4b 100644 --- a/lib/http.c +++ b/lib/http.c @@ -775,6 +775,21 @@ output_auth_headers(struct Curl_easy *data, 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 @@ -847,17 +862,14 @@ Curl_http_output_auth(struct Curl_easy *data, 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 || + /* 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) #ifndef CURL_DISABLE_NETRC - conn->bits.netrc || + || conn->bits.netrc #endif - !data->state.first_host || - data->set.allow_auth_to_other_hosts || - strcasecompare(data->state.first_host, conn->host.name)) { + ) result = output_auth_headers(data, conn, authhost, request, path, FALSE); - } else authhost->done = TRUE; @@ -1913,10 +1925,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, 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 { #ifdef USE_HYPER @@ -2088,6 +2097,7 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn) return CURLE_OUT_OF_MEMORY; data->state.first_remote_port = conn->remote_port; + data->state.first_remote_protocol = conn->handler->protocol; } Curl_safefree(data->state.aptr.host); diff --git a/lib/urldata.h b/lib/urldata.h index d3f337638..ffbe56993 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1324,14 +1324,16 @@ 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. - */ + + /* 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; + int retrycount; /* number of retries on a new connection */ - int first_remote_port; /* remote port of the first (not followed) request */ struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ long sessionage; /* number of the most recent session */ struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */ -- Gitee From aff9e9efb2eb82e59a8947e0739419ae35e56c49 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 13:05:47 +0200 Subject: [PATCH 4/9] test898: verify the fix for CVE-2022-27776 Do not pass on Authorization headers on redirects to another port Signed-off-by: zhouhaifeng --- tests/data/Makefile.inc | 2 +- tests/data/test898 | 90 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 tests/data/test898 diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index c524b993e..3102e686c 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -106,7 +106,7 @@ test854 test855 test856 test857 test858 test859 test860 test861 test862 \ test863 test864 test865 test866 test867 test868 test869 test870 test871 \ test872 test873 test874 test875 test876 test877 test878 test879 test880 \ test881 test882 test883 test884 test885 test886 test887 test888 test889 \ -test890 test891 test892 test893 test894 test895 test896 \ +test890 test891 test892 test893 test894 test895 test896 test897 test898 \ \ test900 test901 test902 test903 test904 test905 test906 test907 test908 \ test909 test910 test911 test912 test913 test914 test915 test916 test917 \ diff --git a/tests/data/test898 b/tests/data/test898 new file mode 100644 index 000000000..314fc83b8 --- /dev/null +++ b/tests/data/test898 @@ -0,0 +1,90 @@ + + + +HTTP +--location +Authorization +Cookie + + + +# +# Server-side + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: http://firsthost.com:9999/a/path/%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 4 +Connection: close +Content-Type: text/html + +hey + + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: http://firsthost.com:9999/a/path/%TESTNUMBER0002 + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 4 +Connection: close +Content-Type: text/html + +hey + + + + +# +# Client-side + + +http + + +HTTP with custom auth and cookies redirected to HTTP on a diff port + + +-x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -H "Authorization: Basic am9lOnNlY3JldA==" -H "Cookie: userpwd=am9lOnNlY3JldA==" + + + +# +# Verify data after the test has been "shot" + + +GET http://firsthost.com/ HTTP/1.1 +Host: firsthost.com +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive +Authorization: Basic am9lOnNlY3JldA== +Cookie: userpwd=am9lOnNlY3JldA== + +GET http://firsthost.com:9999/a/path/%TESTNUMBER0002 HTTP/1.1 +Host: firsthost.com:9999 +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + + + + -- Gitee From ccb4e7c72320c7217b2e8bdfcb97ba6ce3875ff3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 13:05:47 +0200 Subject: [PATCH 5/9] cookie.d: clarify when cookies are always sent Signed-off-by: zhouhaifeng --- docs/cmdline-opts/cookie.d | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/cmdline-opts/cookie.d b/docs/cmdline-opts/cookie.d index 5c40cf2d8..a17414f27 100644 --- a/docs/cmdline-opts/cookie.d +++ b/docs/cmdline-opts/cookie.d @@ -5,9 +5,12 @@ Protocols: HTTP Help: Send cookies from string/file Category: http --- -Pass the data to the HTTP server in the Cookie header. It is supposedly -the data previously received from the server in a "Set-Cookie:" line. The -data should be in the format "NAME1=VALUE1; NAME2=VALUE2". +Pass the data to the HTTP server in the Cookie header. It is supposedly the +data previously received from the server in a "Set-Cookie:" line. The data +should be in the format "NAME1=VALUE1; NAME2=VALUE2". This makes curl use the +cookie header with this content explicitly in all outgoing request(s). If +multiple requests are done due to authentication, followed redirects or +similar, they will all get this cookie passed on. If no '=' symbol is used in the argument, it is instead treated as a filename to read previously stored cookie from. This option also activates the cookie -- Gitee From b7839e4e439fdb39d2907479a52b1f8548af9fd6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 16:24:33 +0200 Subject: [PATCH 6/9] connect: store "conn_remote_port" in the info struct To make it available after the connection ended. Signed-off-by: zhouhaifeng --- lib/connect.c | 1 + lib/urldata.h | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/connect.c b/lib/connect.c index 11e6b888b..7e9045920 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -619,6 +619,7 @@ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, data->info.conn_scheme = conn->handler->scheme; data->info.conn_protocol = conn->handler->protocol; data->info.conn_primary_port = conn->port; + data->info.conn_remote_port = conn->remote_port; data->info.conn_local_port = local_port; } diff --git a/lib/urldata.h b/lib/urldata.h index ffbe56993..a4e905413 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1155,7 +1155,11 @@ struct PureInfo { reused, in the connection cache. */ char conn_primary_ip[MAX_IPADR_LEN]; - int 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]; int conn_local_port; const char *conn_scheme; -- Gitee From bb44e7d6b499b159cddf53adf517efd18d3749b1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 16:24:33 +0200 Subject: [PATCH 7/9] 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 Closes #8748 Signed-off-by: zhouhaifeng --- lib/transfer.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/transfer.c b/lib/transfer.c index 3e650b5b9..78bf349fc 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1652,10 +1652,57 @@ 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; + + if(data->set.use_port && data->state.allow_port) + /* a custom port is used */ + port = (int)data->set.use_port; + else { + 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->state.aptr.user); + Curl_safefree(data->state.aptr.passwd); + } + } } if(type == FOLLOW_FAKE) { -- Gitee From 45797cee8eb5dca0c80e366b3a33f317d16b58c6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 16:24:33 +0200 Subject: [PATCH 8/9] tests: verify the fix for CVE-2022-27774 - Test 973 redirects from HTTP to FTP, clear auth - Test 974 redirects from HTTP to HTTP different port, clear auth - Test 975 redirects from HTTP to FTP, permitted to keep auth - Test 976 redirects from HTTP to HTTP different port, permitted to keep auth Signed-off-by: zhouhaifeng --- tests/data/Makefile.inc | 2 +- tests/data/test973 | 88 +++++++++++++++++++++++++++++++++++++++++ tests/data/test974 | 87 ++++++++++++++++++++++++++++++++++++++++ tests/data/test975 | 88 +++++++++++++++++++++++++++++++++++++++++ tests/data/test976 | 88 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 tests/data/test973 create mode 100644 tests/data/test974 create mode 100644 tests/data/test975 create mode 100644 tests/data/test976 diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 3102e686c..55a752887 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -116,7 +116,7 @@ test936 test937 test938 test939 test940 test941 test942 test943 test944 \ test945 test946 test947 test948 test949 test950 test951 test952 test953 \ test954 test955 test956 test957 test958 test959 test960 test961 test962 \ test963 test964 test965 test966 test967 test968 test969 test970 test971 \ -test972 \ +test972 test973 test974 test975 test976 \ \ test980 test981 test982 test983 test984 test985 test986 \ \ diff --git a/tests/data/test973 b/tests/data/test973 new file mode 100644 index 000000000..219fc37b1 --- /dev/null +++ b/tests/data/test973 @@ -0,0 +1,88 @@ + + + +HTTP +FTP +--location + + + +# +# Server-side + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: ftp://%HOSTIP:%FTPPORT/a/path/%TESTNUMBER0002 + + + +data + to + see +that FTP +works + so does it? + + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: ftp://%HOSTIP:%FTPPORT/a/path/%TESTNUMBER0002 + +data + to + see +that FTP +works + so does it? + + + + +# +# Client-side + + +http +ftp + + +HTTP with auth redirected to FTP w/o auth + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER -L -u joe:secret + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +Authorization: Basic am9lOnNlY3JldA== +User-Agent: curl/%VERSION +Accept: */* + +USER anonymous +PASS ftp@example.com +PWD +CWD a +CWD path +EPSV +TYPE I +SIZE %TESTNUMBER0002 +RETR %TESTNUMBER0002 +QUIT + + + diff --git a/tests/data/test974 b/tests/data/test974 new file mode 100644 index 000000000..5630c42fe --- /dev/null +++ b/tests/data/test974 @@ -0,0 +1,87 @@ + + + +HTTP +--location + + + +# +# Server-side + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: http://firsthost.com:9999/a/path/%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 4 +Connection: close +Content-Type: text/html + +hey + + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: http://firsthost.com:9999/a/path/%TESTNUMBER0002 + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 4 +Connection: close +Content-Type: text/html + +hey + + + + +# +# Client-side + + +http + + +HTTP with auth redirected to HTTP on a diff port w/o auth + + +-x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -u joe:secret + + + +# +# Verify data after the test has been "shot" + + +GET http://firsthost.com/ HTTP/1.1 +Host: firsthost.com +Authorization: Basic am9lOnNlY3JldA== +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + +GET http://firsthost.com:9999/a/path/%TESTNUMBER0002 HTTP/1.1 +Host: firsthost.com:9999 +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + + + + diff --git a/tests/data/test975 b/tests/data/test975 new file mode 100644 index 000000000..53ca03126 --- /dev/null +++ b/tests/data/test975 @@ -0,0 +1,88 @@ + + + +HTTP +FTP +--location-trusted + + + +# +# Server-side + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: ftp://%HOSTIP:%FTPPORT/a/path/%TESTNUMBER0002 + + + +data + to + see +that FTP +works + so does it? + + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: ftp://%HOSTIP:%FTPPORT/a/path/%TESTNUMBER0002 + +data + to + see +that FTP +works + so does it? + + + + +# +# Client-side + + +http +ftp + + +HTTP with auth redirected to FTP allowing auth to continue + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER --location-trusted -u joe:secret + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +Authorization: Basic am9lOnNlY3JldA== +User-Agent: curl/%VERSION +Accept: */* + +USER joe +PASS secret +PWD +CWD a +CWD path +EPSV +TYPE I +SIZE %TESTNUMBER0002 +RETR %TESTNUMBER0002 +QUIT + + + diff --git a/tests/data/test976 b/tests/data/test976 new file mode 100644 index 000000000..77b4b88fb --- /dev/null +++ b/tests/data/test976 @@ -0,0 +1,88 @@ + + + +HTTP +--location-trusted + + + +# +# Server-side + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: http://firsthost.com:9999/a/path/%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 4 +Connection: close +Content-Type: text/html + +hey + + + +HTTP/1.1 301 redirect +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close +Content-Type: text/html +Location: http://firsthost.com:9999/a/path/%TESTNUMBER0002 + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Length: 4 +Connection: close +Content-Type: text/html + +hey + + + + +# +# Client-side + + +http + + +HTTP with auth redirected to HTTP on a diff port --location-trusted + + +-x http://%HOSTIP:%HTTPPORT http://firsthost.com --location-trusted -u joe:secret + + + +# +# Verify data after the test has been "shot" + + +GET http://firsthost.com/ HTTP/1.1 +Host: firsthost.com +Authorization: Basic am9lOnNlY3JldA== +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + +GET http://firsthost.com:9999/a/path/%TESTNUMBER0002 HTTP/1.1 +Host: firsthost.com:9999 +Authorization: Basic am9lOnNlY3JldA== +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + + + + -- Gitee From 0cc57888d5a1f476b4ee08a43a6c7c57b779bd0f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 Apr 2022 17:59:15 +0200 Subject: [PATCH 9/9] openssl: don't leak the SRP credentials in redirects either Follow-up to 620ea21410030 Reported-by: Harry Sintonen Closes #8751 Signed-off-by: zhouhaifeng --- 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 180edaf4b..c4427f15a 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) #ifndef CURL_DISABLE_NETRC || conn->bits.netrc #endif @@ -1925,7 +1925,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 { #ifdef USE_HYPER diff --git a/lib/http.h b/lib/http.h index bce171550..76741c5b0 100644 --- a/lib/http.h +++ b/lib/http.h @@ -317,4 +317,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 8af23b783..2eae2a8ef 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -2866,7 +2866,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #endif #ifdef USE_OPENSSL_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", ssl_username); -- Gitee