From 0a149a1ed9c273921ee43aa23d92d6078bf36a86 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 28 Apr 2022 09:57:23 +0200 Subject: [PATCH] Resolves: CVE-2022-27776 - fix auth/cookie leak on redirect --- 0012-curl-7.76.1-CVE-2022-27776.patch | 243 ++++++++++++++++++++++++++ curl.spec | 5 + 2 files changed, 248 insertions(+) create mode 100644 0012-curl-7.76.1-CVE-2022-27776.patch diff --git a/0012-curl-7.76.1-CVE-2022-27776.patch b/0012-curl-7.76.1-CVE-2022-27776.patch new file mode 100644 index 0000000..7dd5fdf --- /dev/null +++ b/0012-curl-7.76.1-CVE-2022-27776.patch @@ -0,0 +1,243 @@ +From 2be87227d4b4024c91ff6c856520cac9c9619555 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 13:05:40 +0200 +Subject: [PATCH 1/2] 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 + +Upstream-commit: 6e659993952aa5f90f48864be84a1bbb047fc258 +Signed-off-by: Kamil Dudka +--- + lib/http.c | 33 +++++++++++++++++++++------------ + lib/urldata.h | 16 +++++++++------- + 2 files changed, 30 insertions(+), 19 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index 799d4fb..0791dcf 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,15 +862,11 @@ 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 || +- 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(data, conn, authhost, request, path, FALSE); +- } + else + authhost->done = TRUE; + +@@ -1906,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 +@@ -2081,6 +2089,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 03da59a..f92052a 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1336,14 +1336,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 */ +-- +2.34.1 + + +From c0d12f1634785596746e5d461319dcb95b5b6ae8 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 13:05:47 +0200 +Subject: [PATCH 2/2] test898: verify the fix for CVE-2022-27776 + +Do not pass on Authorization headers on redirects to another port + +Upstream-commit: afe752e0504ab60bf63787ede0b992cbe1065f78 +Signed-off-by: Kamil Dudka +--- + 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 59d46bc..7ae2cf8 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 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 0000000..5cbb7d8 +--- /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 ++ ++ ++ ++ +-- +2.34.1 + diff --git a/curl.spec b/curl.spec index d1e19cd..977fcdd 100644 --- a/curl.spec +++ b/curl.spec @@ -38,6 +38,9 @@ Patch10: 0010-curl-7.76.1-CVE-2022-22576.patch # fix bad local IPv6 connection reuse (CVE-2022-27775) Patch11: 0011-curl-7.76.1-CVE-2022-27775.patch +# fix auth/cookie leak on redirect (CVE-2022-27776) +Patch12: 0012-curl-7.76.1-CVE-2022-27776.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.32.0-multilib.patch @@ -224,6 +227,7 @@ be installed. %patch9 -p1 %patch10 -p1 %patch11 -p1 +%patch12 -p1 # Fedora patches %patch101 -p1 @@ -445,6 +449,7 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %changelog * Thu Apr 28 2022 Kamil Dudka - 7.76.1-15 +- fix auth/cookie leak on redirect (CVE-2022-27776) - fix bad local IPv6 connection reuse (CVE-2022-27775) - fix OAUTH2 bearer bypass in connection re-use (CVE-2022-22576)