-
Notifications
You must be signed in to change notification settings - Fork 913
HTTP/3: upgrade header forwarded #2928
Copy link
Copy link
Closed
Labels
status: fixedThis issue is a now-fixed bug.This issue is a now-fixed bug.type: bugThis issue describes a bug.This issue describes a bug.
Description
Detailed Description of the Problem
An HTTP/3 request containing the upgrade header is forwarded without modification.
The upgrade header is not supported in HTTP/3, as RFC 9114 states:
4.5. HTTP Upgrade
HTTP/3 does not support the HTTP Upgrade mechanism (Section 7.8 of [HTTP]) or the 101 (Switching Protocols) informational status code (Section 15.2.2 of [HTTP]).
This could cause issues, esp. with HTTP/1.1 backend servers.
Expected Behavior
If a client sends an upgrade header in a request, it should be either deleted or the request should be considered as malformed and be rejected, since the upgrade header would influence the backend communication. Rejecting is best practice in my opinion.
Steps to Reproduce the Behavior
- Setup an environment where haproxy forwards HTTP/3 requests to an HTTP/1.1 backend.
- Send a request containing the
ugpradeheader (curl with HTTP/3 does not support this, use something like aioquic. - Observe traffic using wireshark or let backend print the received request.
Do you have any idea what may have caused this?
No response
Do you have an idea how to solve the issue?
No response
What is your configuration?
frontend http_in
mode http
bind :80
bind :443 ssl crt /PATH/TO/KEY alpn h2
bind quic4@:443 ssl crt /PATH/TO/KEY alpn h3
http-request redirect scheme https unless { ssl_fc }
http-after-response add-header alt-svc 'h3=":443"; ma=60'
default_backend http_backend
backend http_backend
server backend1 127.0.0.1:8080Output of haproxy -vv
HAProxy version 3.1.5-076df02 2025/02/20 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-3.1.5.html
Running on: Linux 6.11.0-21-generic #21~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Feb 24 16:52:15 UTC 2 x86_64
Build options :
TARGET = linux-glibc
CC = cc
CFLAGS = -O2 -g -fwrapv
OPTIONS = USE_OPENSSL=1 USE_LUA=1 USE_ZLIB=1 USE_QUIC=1 USE_PROMEX=1 USE_PCRE=1
DEBUG =
Feature list : -51DEGREES +ACCEPT4 +BACKTRACE -CLOSEFROM +CPU_AFFINITY +CRYPT_H -DEVICEATLAS +DL -ENGINE +EPOLL -EVPORTS +GETADDRINFO -KQUEUE -LIBATOMIC +LIBCRYPT +LINUX_CAP +LINUX_SPLICE +LINUX_TPROXY +LUA +MATH -MEMORY_PROFILING +NETFILTER +NS -OBSOLETE_LINKER +OPENSSL -OPENSSL_AWSLC -OPENSSL_WOLFSSL -OT +PCRE -PCRE2 -PCRE2_JIT -PCRE_JIT +POLL +PRCTL -PROCCTL +PROMEX -PTHREAD_EMULATION +QUIC -QUIC_OPENSSL_COMPAT +RT +SHM_OPEN -SLZ +SSL -STATIC_PCRE -STATIC_PCRE2 +TFO +THREAD +THREAD_DUMP +TPROXY -WURFL +ZLIB
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_TGROUPS=16, MAX_THREADS=256, default=16).
Built with OpenSSL version : OpenSSL 1.1.1t+quic 7 Feb 2023
Running on OpenSSL version : OpenSSL 1.1.1t+quic 7 Feb 2023
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with Lua version : Lua 5.3.6
Built with the Prometheus exporter as a service
Built with network namespace support.
Built with zlib version : 1.3
Running on zlib version : 1.3
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE version : 8.39 2016-06-14
Running on PCRE version : 8.39 2016-06-14
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Encrypted password support via crypt(3): yes
Built with gcc compiler version 13.3.0
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
quic : mode=HTTP side=FE mux=QUIC flags=HTX|NO_UPG|FRAMED
h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG
<default> : mode=HTTP side=FE|BE mux=H1 flags=HTX
h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG
fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG
<default> : mode=SPOP side=BE mux=SPOP flags=HOL_RISK|NO_UPG
spop : mode=SPOP side=BE mux=SPOP flags=HOL_RISK|NO_UPG
<default> : mode=TCP side=FE|BE mux=PASS flags=
none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG
Available services : prometheus-exporter
Available filters :
[BWLIM] bwlim-in
[BWLIM] bwlim-out
[CACHE] cache
[COMP] compression
[FCGI] fcgi-app
[SPOE] spoe
[TRACE] trace
Last Outputs and Backtraces
00000000:http_in.accept(0004)=7cc0 from [127.0.0.1:51576] ALPN=h3
00000000:http_in.clireq[7cc0:ffffffff]: POST / HTTP/3.0
00000000:http_in.clihdr[7cc0:ffffffff]: host: localhost:443
00000000:http_in.clihdr[7cc0:ffffffff]: upgrade: test
00000000:http_backend.srvrep[7cc0:0038]: HTTP/1.1 200 OK
00000000:http_backend.srvhdr[7cc0:0038]: content-length: 85
00000000:http_backend.srvhdr[7cc0:0038]: content-type: text/plain
00000000:http_backend.srvcls[ffff:0038]
00000000:http_backend.clicls[ffff:0038]
00000000:http_backend.closed[ffff:0038]
Additional Information
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
status: fixedThis issue is a now-fixed bug.This issue is a now-fixed bug.type: bugThis issue describes a bug.This issue describes a bug.