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
This commit is contained in:
Stefan Eissing 2026-03-27 09:19:34 +01:00 committed by Daniel Stenberg
parent 351e4f956a
commit 2e8c922a89
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View file

@ -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);