transfer: adapt Curl_xfer_is_secure()

Now that `conn->origin` can be the proxy, we need to change how
Curl_xfer_is_secure() and some other places work.

Pointed out by Codex Security

Closes #22015
This commit is contained in:
Stefan Eissing 2026-06-15 09:10:28 +02:00 committed by Daniel Stenberg
parent 03bc93bd32
commit 8cc3fed7df
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
7 changed files with 23 additions and 23 deletions

View file

@ -555,6 +555,14 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
CURL_TRC_CF(data, cf, "Curl_conn_connect(block=%d) -> %d, done=%d",
blocking, (int)result, *done);
if(!result && *done) {
/* A final sanity check on connection security */
if((data->state.origin->scheme->flags & PROTOPT_SSL) &&
(sockindex == FIRSTSOCKET) &&
!Curl_conn_is_ssl(data->conn, FIRSTSOCKET)) {
DEBUGASSERT(0);
failf(data, "transfer requires SSL, but not connected via SSL");
return CURLE_FAILED_INIT;
}
/* Now that the complete filter chain is connected, let all filters
* persist information at the connection. E.g. cf-socket sets the
* socket and ip related information. */

View file

@ -496,7 +496,7 @@ static CURLcode cf_setup_add_origin_filters(struct Curl_cfilter *cf,
#ifdef USE_SSL
if((ctx->ssl_mode == CURL_CF_SSL_ENABLE ||
(ctx->ssl_mode != CURL_CF_SSL_DISABLE &&
cf->conn->scheme->flags & PROTOPT_SSL)) && /* we want SSL */
data->state.origin->scheme->flags & PROTOPT_SSL)) && /* we want SSL */
!Curl_conn_is_ssl(cf->conn, cf->sockindex)) { /* it is missing */
#ifndef CURL_DISABLE_PROXY

View file

@ -4938,7 +4938,7 @@ CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers,
infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme);
}
else {
scheme = Curl_xfer_is_secure(data) ? "https" : "http";
scheme = data->state.origin->scheme->name;
}
}

View file

@ -1076,7 +1076,7 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data,
line += wordlen;
}
}
else if(data->set.use_ssl && !Curl_xfer_is_secure(data)) {
else if(data->set.use_ssl && !Curl_conn_is_ssl(data->conn, FIRSTSOCKET)) {
/* PREAUTH is not compatible with STARTTLS. */
if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) {
/* Switch to TLS connection now */

View file

@ -903,22 +903,14 @@ CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable)
bool Curl_xfer_is_secure(struct Curl_easy *data)
{
const struct Curl_scheme *scheme = NULL;
if(data->conn) {
scheme = data->conn->scheme;
/* if we are connected, but not use SSL, the transfer is not secure.
* This covers an insecure http:// proxy that is not tunneling.
* We enforce tunneling for such cases, but better be sure here. */
if(Curl_conn_is_connected(data->conn, FIRSTSOCKET) &&
!Curl_conn_is_ssl(data->conn, FIRSTSOCKET))
return FALSE;
#ifndef CURL_DISABLE_PROXY
if(data->conn && data->conn->bits.origin_is_proxy) {
/* talking to a forward proxy, not secure. we do not use
* a forward proxy for https: and other 's' URLs. Let's just check that
* this did not fail somewhere. */
DEBUGASSERT(!(data->state.origin->scheme->flags & PROTOPT_SSL));
return FALSE;
}
else if(data->info.conn_scheme) { /* was connected once */
scheme = Curl_get_scheme(data->info.conn_scheme);
}
else { /* never connected (yet?) */
DEBUGASSERT(0); /* not implemented, would need to parse URL */
}
return scheme ? (scheme->flags & PROTOPT_SSL) : FALSE;
#endif
return (data->state.origin->scheme->flags & PROTOPT_SSL);
}

View file

@ -143,8 +143,8 @@ bool Curl_xfer_recv_is_paused(struct Curl_easy *data);
CURLcode Curl_xfer_pause_send(struct Curl_easy *data, bool enable);
CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable);
/* TRUE if the transfer is secure (e.g. TLS) from libcurl to the
* URL's host. */
/* TRUE if the transfer is secure, e.g. uses TLS and does not
* use a forward proxy. */
bool Curl_xfer_is_secure(struct Curl_easy *data);
#endif /* HEADER_CURL_TRANSFER_H */

View file

@ -867,7 +867,7 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data,
failf(data, "HTTP/3 cannot be used over UNIX domain sockets");
return CURLE_QUIC_CONNECT_ERROR;
}
if(!(conn->scheme->flags & PROTOPT_SSL)) {
if(!(data->state.origin->scheme->flags & PROTOPT_SSL)) {
failf(data, "HTTP/3 requested for non-HTTPS URL");
return CURLE_URL_MALFORMAT;
}