Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
-*- coding: utf-8 -*-
Changes with Apache 2.4.70

*) core: Do not offer 'h2' via the Upgrade response header on TLS
connections. RFC 9113 requires HTTP/2 over TLS to be negotiated
via ALPN only. PR 59311

Changes with Apache 2.4.69

*) SECURITY: CVE-2026-93546: mod_dav_fs namespace overflow
Expand Down
7 changes: 7 additions & 0 deletions server/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "http_main.h"
#include "http_request.h"
#include "http_vhost.h"
#include "http_ssl.h"
#include "http_log.h" /* For errors detected in basic auth common
* support code... */
#include "mod_core.h"
Expand Down Expand Up @@ -2428,6 +2429,12 @@ AP_DECLARE(apr_status_t) ap_get_protocol_upgrades(conn_rec *c, request_rec *r,
sizeof(char *));
for (i = 0; i < conf->protocols->nelts; i++) {
const char *p = APR_ARRAY_IDX(conf->protocols, i, char *);
/* RFC 9113, Section 3.3: HTTP/2 over TLS is negotiated
* exclusively via ALPN; 'h2' must never be offered through
* the HTTP/1.1 Upgrade mechanism on a TLS connection. */
if (!strcmp("h2", p) && ap_ssl_conn_is_ssl(c)) {
continue;
}
if (strcmp(existing, p)) {
/* not the one we have and possible, add in this order */
APR_ARRAY_PUSH(upgrades, const char*) = p;
Expand Down
6 changes: 3 additions & 3 deletions test/modules/http2/test_103_upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ def test_h2_103_05(self, env):
assert r.response
assert "upgrade" not in r.response["header"]

# accessing https://test1, will advertise h2 in the response
# accessing https://test1, must not advertise h2 in the response: RFC 9113
# section 3.3 requires HTTP/2 over TLS to be negotiated via ALPN only.
def test_h2_103_06(self, env):
url = env.mkurl("https", "test1", "/index.html")
r = env.curl_get(url, options=["--http1.1"])
assert 0 == r.exit_code
assert r.response
assert "upgrade" in r.response["header"]
assert "h2" == r.response["header"]["upgrade"]
assert "upgrade" not in r.response["header"]

# accessing https://test3, will not send Upgrade since it is suppressed
def test_h2_103_07(self, env):
Expand Down
Loading