- From: Egor Gudzenko <egor@egl.sh>
- Date: Sun, 07 Jun 2026 23:07:26 +0000
- To: Lucas Pardue <lucas@lucaspardue.com>
- Cc: "ietf-http-wg@w3.org" <ietf-http-wg@w3.org>
- Message-ID: <e-9W1Mz3fAN1zYWTh2MWpshZdxI4CAsG7csGCjREf5YjejVLtJNVuS9HHBbfg8hwGHeV5IaBAX2lMy3>
Hi Lucas,
Sorry for a pretty late response and for this wall of text.
You're right, forcing a server to choose the cipher suite when h2 has not yet been selected as the negotiated protocol is a bit too much. A better formulation would be:
> When a TLS 1.2 server's ServerHello will include 'h2' as the ALPN-selected protocol, and the intersection of cipher suites offered in the ClientHello and supported by the server includes at least one h2-compatible cipher suite, the server SHOULD select an h2-compatible cipher suite.
As for the data — I don't think an honest count exists. Cloudflare Radar, derived from traffic through Cloudflare's network and the 1.1.1.1 resolver, does not publish the intersection of TLS 1.2, cipher selected from Appendix A, and negotiated ALPN. Broader scanning would not close the gap either: private infrastructure is not reachable from public Internet scans.
What can be shown is that the precondition for this failure mode is present in the shipped defaults of independent classes of software supporting HTTP/2 over TLS 1.2. Section 9.2.2 documents the failure mode, but that has not produced consistent behavior across implementations — which is what motivates the normative requirement in Section 4.
**OS-level TLS provider.** Microsoft Schannel on Windows Server 2022 and 2025 ships a default priority list that contains both h2-compatible suites (e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) and Appendix A prohibited suites (TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, and others). "HTTP/2 web services fail with non-HTTP/2-compatible cipher suites. To ensure your web services function with HTTP/2 clients and browsers, see How to deploy custom cipher suite ordering." [1] Microsoft's own documentation confirms the failure mode occurs — yet the precondition remains in the shipped default.
**Reverse proxies and network appliances.** F5 BIG-IP ships built-in read-only cipher groups including f5-hw_keys, which mixes ECDHE-GCM suites (h2-compatible) with AES256-SHA256 and AES256-SHA (all in Appendix A). [2] The f5-secure built-in group similarly mixes ECDHE-GCM with AES128-SHA and AES256-SHA. [3] AWS Application Load Balancer's default security policy when listeners are provisioned via the AWS CLI, CloudFormation, or CDK is ELBSecurityPolicy-2016-08, which contains four h2-compatible ECDHE-GCM suites alongside fourteen Appendix A suites including ECDHE-RSA-AES128-SHA256, ECDHE-RSA-AES128-SHA, AES128-GCM-SHA256, AES128-SHA, and AES256-SHA. [4]
**General-purpose web servers.** nginx's documented default is ssl_ciphers HIGH:!aNULL:!MD5. [5] OpenSSL's HIGH group includes TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, and TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 — all in Appendix A — alongside h2-compatible ECDHE-GCM suites.
**Application runtimes.** Node.js ships a default cipher list that explicitly includes TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 and TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 in its curated prefix — all in Appendix A — in addition to prohibited suites inherited via HIGH. The documentation shows users manually removing RSA-kx and ECDHE-CBC suites as a recommended hardening step, which itself confirms their presence in the default. [6]
The precondition appears across four independent categories of software. It is this recurrence across unrelated implementations — not the prevalence within any one category — that Section 4 is intended to address.
This draft was informed by an incident I investigated, and the mechanism described below is independently documented in public reports.
One such report is the Palantir conjure-java-runtime issue #394 (2017) https://github.com/palantir/conjure-java-runtime/issues/394. The mechanism is easy to reproduce: a server configured with prohibited cipher suites in priority position will select one when the ClientHello offers both compliant and non-compliant options. The same applies to servers that follow client cipher order: if the first cipher offered in the ClientHello is prohibited, the server will select it regardless of h2-compatible alternatives present later in the list.
RFC 9113 permits clients to forgo enforcement of Section 9.2.2 — the requirement uses MAY. curl, nghttp2, and Go's golang.org/x/net/http2 client do not raise INADEQUATE_SECURITY when h2 is negotiated over a prohibited cipher; I verified this against TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA. The failure mode does not surface with these clients and manifests only when a client enforces Section 9.2.2 — browsers, for example, do.
There is also a security argument I should have included in the original draft. Section 6 frames the procedure as addressing availability. That understates it. Section 9.2.2 only protects clients that enforce it. For non-enforcing clients, the server's selection of a prohibited cipher results in a successfully established HTTP/2 session over a suite the HTTP Working Group determined unfit for HTTP/2. Section 4 raises the cryptographic floor of every such session, not only those where the client enforces. I'll revise Section 6 accordingly.
On practical implementation: the procedure in Section 4 can be satisfied at the configuration level when server-side cipher ordering is enabled — by placing h2-compatible suites ahead of prohibited ones. The stronger form is library-level ALPN-aware cipher filtering: when "h2" is the selected ALPN value, the negotiable set is restricted to h2-compatible suites regardless of cipher order preference. This covers both server-side and client-side ordering scenarios, and raises the cryptographic floor for all HTTP/2 over TLS 1.2 sessions regardless of operator configuration. If the WG finds this worth pursuing, I'm happy to work these points into a next revision.
With regards,
Egor Gudzenko
[1] TLS Cipher Suites in Windows Server 2022 and 2025.
https://learn.microsoft.com/en-us/windows/win32/secauthn/tls-cipher-suites-in-windows-server-2022
https://learn.microsoft.com/en-us/windows/win32/secauthn/tls-cipher-suites-in-windows-server-2025
[2] Cipher Rules and Groups in BIG-IP v13. F5 DevCentral (2017).
https://community.f5.com/kb/technicalarticles/cipher-rules-and-groups-in-big-ip-v13/279555
[3] BIG-IP System SSL Administration 21.1.0. F5 TechDocs (updated 2026).
https://techdocs.f5.com/en-us/bigip-21-1-0/big-ip-system-ssl-administration/ssl-traffic-management.html
[4] Security policies for your Application Load Balancer. AWS documentation.
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/describe-ssl-policies.html
[5] Configuring HTTPS servers. nginx documentation.
https://nginx.org/en/docs/http/configuring_https_servers.html
[6] TLS — Modifying the default TLS cipher suite. Node.js documentation.
https://nodejs.org/api/tls.html
On Tuesday, May 26th, 2026 at 17:22, Lucas Pardue <lucas@lucaspardue.com> wrote:
> Hi Egor,
>
> Thanks for emailing the list.
>
> On Sat, May 23, 2026, at 14:32, Egor Gudzenko wrote:
>
> > Hi,
> >
> > I've submitted an individual draft addressing the failure mode noted in Section 9.2.2 of RFC 9113, where HTTP/2 may be negotiated with a prohibited cipher suite.
> >
> > https://datatracker.ietf.org/doc/draft-gudzenko-httpbis-h2-cipher-selection/
> >
> > The draft adds a single SHOULD-level procedure: when an h2-compatible cipher suite is available in the negotiation, the server should prefer it. It doesn't change anything normative, and the only subject of this draft is to fill a normative gap that are identified in Section 9.2.2 but not described how the server should behave in an ideal world.
> >
> > I filed it as Standards Track with updates: 9113, since the gap it closes is in normative text and a SHOULD-level addition doesn't fit BCP or Informational cleanly. That said, I'm genuinely uncertain whether this warrants a standalone update to 9113 or whether WG sees a better path.
> >
> > Any feedback welcome.
>
>
> My read of the I-D is that is it proposing a normative change for H2 servers. Focusing specifically on the proposed text that in Section 4 [1]
>
> > When a TLS 1.2 server receives a ClientHello that includes "h2" in the ALPN extension [RFC7301], and the intersection of cipher suites offered in the ClientHello and supported by the server includes at least one h2-compatible cipher suite, the server SHOULD select an h2-compatible cipher suite.
>
> The construction there is problematic. For instance, both clients and servers are typically configured with a priority preference order for ciphersuite and ALPN set. The presence of "h2" in a ClientHello is not expressive of the full situation. For example, if both client and server prefer h1 over h2, then requiring anything of the ciphersuite is likely overstepping.
>
> The deployment challenges are laid out pretty clear in RFC 9113. How much of a problem is there in reality? How practical is the advice for TLS library usage? I think the WG would need to see some compelling data to warrant such spec updates.
>
> Cheers
> Lucas
>
> [1] https://www.ietf.org/archive/id/draft-gudzenko-httpbis-h2-cipher-selection-00.html#section-4
>
>
>
> ------------------------
>
>
>
> >
> > With regards,
> > Egor Gudzenko
> >
> >
> >
> > Attachments:
> >
> > - publickey - egor@egl.sh - 0xAE5C7632.asc
> > - signature.asc
>
>
Attachments
- application/pgp-keys attachment: publickey_-_egor_egl.sh_-_0xAE5C7632.asc
Received on Sunday, 7 June 2026 23:07:41 UTC