You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.6 KiB
243 lines
7.6 KiB
From 2be87227d4b4024c91ff6c856520cac9c9619555 Mon Sep 17 00:00:00 2001 |
|
From: Daniel Stenberg <daniel@haxx.se> |
|
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 <kdudka@redhat.com> |
|
--- |
|
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 <daniel@haxx.se> |
|
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 <kdudka@redhat.com> |
|
--- |
|
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 @@ |
|
+<testcase> |
|
+<info> |
|
+<keywords> |
|
+HTTP |
|
+--location |
|
+Authorization |
|
+Cookie |
|
+</keywords> |
|
+</info> |
|
+ |
|
+# |
|
+# Server-side |
|
+<reply> |
|
+<data> |
|
+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 |
|
+ |
|
+</data> |
|
+<data2> |
|
+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 |
|
+</data2> |
|
+ |
|
+<datacheck> |
|
+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 |
|
+</datacheck> |
|
+ |
|
+</reply> |
|
+ |
|
+# |
|
+# Client-side |
|
+<client> |
|
+<server> |
|
+http |
|
+</server> |
|
+ <name> |
|
+HTTP with custom auth and cookies redirected to HTTP on a diff port |
|
+ </name> |
|
+ <command> |
|
+-x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -H "Authorization: Basic am9lOnNlY3JldA==" -H "Cookie: userpwd=am9lOnNlY3JldA==" |
|
+</command> |
|
+</client> |
|
+ |
|
+# |
|
+# Verify data after the test has been "shot" |
|
+<verify> |
|
+<protocol> |
|
+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 |
|
+ |
|
+</protocol> |
|
+</verify> |
|
+</testcase> |
|
-- |
|
2.34.1 |
|
|
|
|