diff options
author | Daniel Stenberg <daniel@haxx.se> | 2022-04-25 13:05:40 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2022-04-25 13:05:40 +0200 |
commit | 6e659993952aa5f90f48864be84a1bbb047fc258 (patch) | |
tree | 08dbb67fe7b4a615f640a001ae5850f834d90d18 /lib/http.c | |
parent | 8f2079154f80561ccffcaa954268798b658e66b6 (diff) | |
download | curl-6e659993952aa5f90f48864be84a1bbb047fc258.tar.gz |
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
Diffstat (limited to 'lib/http.c')
-rw-r--r-- | lib/http.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/lib/http.c b/lib/http.c index ce79fc4e3..f0476f3b9 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; @@ -1905,10 +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 */ - (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 @@ -2084,6 +2093,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); |