From 2e8c922a89153083227a8f6b737f15bbe9fe1446 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Fri, 27 Mar 2026 09:19:34 +0100 Subject: [PATCH] http2: prevent secure schemes pushed over insecure connections When assembling the URL of a pushed resource over a not-secured connection, require the scheme to be known and not secure. Reported-by: xkilua on hackerone Closes #21113 --- lib/http2.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/http2.c b/lib/http2.c index 56aa798d0d..8a472da4b2 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -718,7 +718,7 @@ static struct Curl_easy *h2_duphandle(struct Curl_cfilter *cf, return second; } -static int set_transfer_url(struct Curl_easy *data, +static int set_transfer_url(struct Curl_easy *data, bool via_ssl_conn, struct curl_pushheaders *hp) { const char *v; @@ -732,6 +732,14 @@ static int set_transfer_url(struct Curl_easy *data, v = curl_pushheader_byname(hp, HTTP_PSEUDO_SCHEME); if(v) { + if(!via_ssl_conn) { + /* PUSH over an insecure connection, accept only insecure schemes. */ + const struct Curl_scheme *scheme = Curl_get_scheme(v); + if(!scheme || (scheme->flags & PROTOPT_SSL)) { + rc = 1; + goto fail; + } + } uc = curl_url_set(u, CURLUPART_SCHEME, v, 0); if(uc) { rc = 1; @@ -811,7 +819,8 @@ static int push_promise(struct Curl_cfilter *cf, heads.stream = stream; heads.frame = frame; - rv = set_transfer_url(newhandle, &heads); + rv = set_transfer_url(newhandle, + Curl_conn_is_ssl(cf->conn, cf->sockindex), &heads); if(rv) { CURL_TRC_CF(data, cf, "[%d] PUSH_PROMISE, failed to set URL -> %d", frame->promised_stream_id, rv);