]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http: in alt-svc negotiation only allow supported HTTP versions
authorSören Tempel <soeren+git@soeren-tempel.net>
Sat, 12 Apr 2025 16:09:47 +0000 (18:09 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 15 Apr 2025 21:09:10 +0000 (23:09 +0200)
Without this patch, the handling of the alt-svc header added via
279a4772ae67dd4d9770e11e60040f9113b1c345 in curl-8.13.0 attempts to
connect to alternative services via different HTTP versions, even if the
target HTTP version is not supported by curl (i.e., not enabled at
compile-time). If I understand the code and RFC 7838 correctly, then we
should only attempt to migrate to supported protocols. Therefore,
`allowed_apns` should only contain such protocols, and we need to guard
its modification with `ifdefs` for supported HTTP versions.

This was discovered in a downstream bug report in Alpine Linux [1] where
it was reported that a Matrix client (using libcurl) was defunct after
the upgrade to curl-8.13.0. Further debugging revealed that this was due
to the Matrix server sending a `alt-svc: h3=":443";` HTTP header,
causing curl to attempt migration to HTTP3 even though Alpine's curl
version is compiled without HTTP3 support.

I am not sure if this is the best place in the code to address this
or if the `allowed` bitmask shouldn't contain unsupported versions
in the first place. However, since there are existing `ifdefs` in
this function for source (not destination) ALP selection, it may
be a good fit to address this here.

[1]: https://gitlab.alpinelinux.org/alpine/aports/-/issues/17062

Closes #17037

lib/url.c

index 39d72ac70a4570db3d089d60048714dbb4deedfa..4a9e6b5feab0e57fff802f09b3aa0b429b67c98a 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -3049,10 +3049,14 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
 
     DEBUGF(infof(data, "Alt-svc check wanted=%x, allowed=%x",
                  neg->wanted, neg->allowed));
+#ifdef USE_HTTP3
     if(neg->allowed & CURL_HTTP_V3x)
       allowed_alpns |= ALPN_h3;
+#endif
+#ifdef USE_HTTP2
     if(neg->allowed & CURL_HTTP_V2x)
       allowed_alpns |= ALPN_h2;
+#endif
     if(neg->allowed & CURL_HTTP_V1x)
       allowed_alpns |= ALPN_h1;
     allowed_alpns &= (int)data->asi->flags;