8000 If the HTTP/2 `:authority` contains `/`, HAProxy treats the part after `/` as part of the path · Issue #2941 · haproxy/haproxy · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
If the HTTP/2 :authority contains /, HAProxy treats the part after / as part of the path #2941
Open
@DemiMarie

Description

@DemiMarie

Detailed Description of the Problem

If I send an HTTP/2 request to HAProxy with a :authority pseudo-header that contains /, HAProxy prepends the part including and after the first / to the :path pseudo-header. If an upstream proxy performs path-based access control but does not validate :authority, these checks could be bypassed.

Expected Behavior

HAProxy should reject the request because / is not allowed in :authority pseudo-headers.

Steps to Reproduce the Behavior

  1. Send an HTTP/2 request to HAProxy with :authority: a/b.
  2. Log what the upstream server receives.

Do you have any idea what may have caused this?

HAProxy forms a request URI by string concatenation, then re-parses it to determine the path to send upstream for HTTP/1.x requests. This is only safe if parsing the URI will result in the same path that was used to form the URI, but in this case it does not.

Do you have an idea how to solve the issue?

HAProxy should strictly validate the :authority and Host headers. In particular, it should reject:

These rules come from Envoy (https://envoyproxy.io).

What is your configuration?

global
   log stderr local0 debug
   chroot /run/haproxy
   maxconn 4000
   limited-quic
   user haproxy
   group haproxy
   stats socket /run/haproxy/haproxy-stats
   ssl-default-bind-curves X25519:P-256:P-384
   ssl-default-bind-ciphersuites TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256
   ssl-default-bind-options prefer-client-ciphers ssl-min-ver TLSv1.3
   unix-bind prefix /run/haproxy user haproxy mode 0660 group qubes
   setcap cap_net_bind_service
defaults
   log global
   timeout client 3000ms
   timeout connect 3000ms
   timeout server 3000ms
crt-store
   load key '/usr/local/etc/haproxy.key' crt /usr/local/etc/haproxy.pem alias 'main'
frontend main
   mode http
   default_backend app
   bind quic4@*:443 ssl crt "@/main" name main_quic_v4
   bind quic6@*:443 ssl crt "@/main" name main_quic_v6
   bind       *:443 ssl crt "@/main" name main_tls
   option httplog
   http-request deny status 400 unless { path_beg '/test/' }
frontend local_socket
   bind /reroute
   mode http
   default_backend trivial
   option httplog
backend app
   mode http
   server reroute /reroute proto h2
backend trivial
   mode http
   server simple /launch proto h1
   option http-server-close

Output of haproxy -vv

HAProxy version 3.1.7 2025/04/17 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-3.1.7.html
Running on: Linux 6.12.21-1.qubes.fc37.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Mar 31 11:38:40 GMT 2025 x86_64
Build options :
  TARGET  = linux-glibc
  CC      = cc
  CFLAGS  = -O2 -g -fwrapv
  OPTIONS = USE_PTHREAD_EMULATION=0 USE_OPENSSL=1 USE_LUA=1 USE_QUIC=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_QUIC_OPENSSL_COMPAT=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=2).
Built with OpenSSL version : OpenSSL 3.2.4 11 Feb 2025
Running on OpenSSL version : OpenSSL 3.2.4 11 Feb 2025
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
OpenSSL providers loaded : default
Built with Lua version : Lua 5.4.7
Built with network namespace support.
Built with libslz for stateless compression.
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 PCRE2 version : 10.44 2024-06-07
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with gcc compiler version 14.2.1 20250110 (Red Hat 14.2.1-7)

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 : none

Available filters :
	[BWLIM] bwlim-in
	[BWLIM] bwlim-out
	[CACHE] cache
	[COMP] compression
	[FCGI] fcgi-app
	[SPOE] spoe
	[TRACE] trace

Last Outputs and Backtraces


Additional Information

This should also reproduce with HTTP/3 requests in the development branch. Envoy Proxy has a readable implementation of the above-mentioned validation logic in https://github.com/envoyproxy/envoy/blob/72fd99b8c3681e413eb40ecaebfb1c3454810763/source/extensions/http/header_validators/envoy_default/header_validator.cc, but this is licensed under Apache 2.0 and is in C++.

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.0This issue affects the HAProxy 3.0 stable branch.status: fixedThis issue is a now-fixed bug.type: bugThis issue describes a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0