File curl-CVE-2022-27776.patch of Package curl.37304
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
---
lib/http.c | 34 ++++++++++++++++++++++------------
lib/urldata.h | 16 +++++++++-------
2 files changed, 31 insertions(+), 19 deletions(-)
Index: curl-7.37.0/lib/http.c
===================================================================
--- curl-7.37.0.orig/lib/http.c
+++ curl-7.37.0/lib/http.c
@@ -638,6 +638,23 @@ output_auth_headers(struct connectdata *
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 connectdata *conn)
+{
+ // struct connectdata *conn = data->conn;
+ struct SessionHandle *data = conn->data;
+
+ return (!data->state.this_is_a_follow ||
+ data->set.allow_auth_to_other_hosts ||
+ (data->state.first_host &&
+ Curl_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
@@ -706,15 +723,14 @@ Curl_http_output_auth(struct connectdata
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 ||
- Curl_raw_equal(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(conn)
+#ifndef CURL_DISABLE_NETRC
+ || conn->bits.netrc
+#endif
+ )
result = output_auth_headers(conn, authhost, request, path, FALSE);
- }
else
authhost->done = TRUE;
@@ -1638,10 +1654,7 @@ CURLcode Curl_add_custom_headers(struct
else if(checkprefix("Authorization:", headers->data) &&
/* 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 &&
- !Curl_raw_equal(data->state.first_host, conn->host.name)))
+ !allow_auth_to_host(conn))
;
else {
CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
@@ -1795,6 +1808,9 @@ CURLcode Curl_http(struct connectdata *c
data->state.first_host = strdup(conn->host.name);
if(!data->state.first_host)
return CURLE_OUT_OF_MEMORY;
+
+ data->state.first_remote_port = conn->remote_port;
+ data->state.first_remote_protocol = conn->handler->protocol;
}
http->writebytecount = http->readbytecount = 0;
Index: curl-7.37.0/lib/urldata.h
===================================================================
--- curl-7.37.0.orig/lib/urldata.h
+++ curl-7.37.0/lib/urldata.h
@@ -1221,11 +1221,14 @@ struct UrlState {
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
- char *first_host; /* 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;
+
struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
long sessionage; /* number of the most recent session */
char *tempwrite; /* allocated buffer to keep data in when a write