Enabling HTTP/2 on the servlet container increases the attack surface: the cleartext upgrade (h2c) behind a proxy allows bypassing the proxy’s access controls, and HTTP/2 implementations have a history of denial of service vulnerabilities (Rapid Reset, CONTINUATION flood, which included a Tomcat CVE).
I believe the same arguments apply for HTTP/3
By stating explicitly that we only support HTTP/1, I think that we would benefit from:
Being able to reject/prioritize related issues easily
Avoid having to extend our functional tests to cover more HTTP versions.
Proposal:
XWiki only support HTTP/1 at servlet container level. Maintainers can fix issues related to other HTTP versions (e.g., Loading...) on the best effort basis.
This includes only providing pre-packaged versions of XWiki with an HTTP/1 support (e.g., Jetty standalone, docker images).
XWiki keeps documenting reverse proxy configurations allowing to access XWiki using other HTTP versions.
I agree with the general idea, but I’d tweak the wording a bit.
I agree that for the common setup (reverse proxy + servlet container), HTTP/2 between the proxy and the container doesn’t bring much. Its main benefit is multiplexing lots of small requests over a high-latency link, and that’s the browser ↔ proxy link, which already works. nginx doesn’t even speak HTTP/2 to backends. On xwiki.org a doc page makes ~155 requests, 139 of them under 10 KB, so HTTP/2 does matter for XWiki, but at the proxy level.
However:
The bugs are in our code, not in HTTP/2. I did some archeology. XWIKI-15768 (2018) looked up a component using the protocol string. XWIKI-18513 relies on statusText. XWIKI-25202 (the cause of the 3 forum threads) is us putting newlines in a header, which the HTTP/2 spec forbids and which Tomcat silently cleans up for us over HTTP/1.1. These are spec-compliance bugs and cheap to fix, so I think we should keep handling them as normal bugs, not best effort.
The security argument cuts both ways. h2c is a real risk, and I agree we should explicitly discourage it. But James Kettle’s 2025 research (“HTTP/1.1 Must Die”, HTTP/1.1 must die: the desync endgame | PortSwigger Research) argues that HTTP/1.1 between the proxy and the backend is the inherently smuggling-prone part, and that upstream HTTP/2 is the fix. So I wouldn’t present “HTTP/1.1 only” as a security measure.
Some users run Tomcat with TLS directly, without a proxy. For them HTTP/2 is a real performance gain.
So my proposal: state that HTTP/1.1 is the tested and recommended protocol at the servlet container level, that the recommended way to get HTTP/2 or HTTP/3 is a reverse proxy, and that h2c is discouraged. Keep the packaged distributions on HTTP/1.1 and don’t extend our functional tests, but keep fixing HTTP/2 incompatibilities in our code as regular bugs.