Hi,

HAProxy 3.0.20 was released on 2026/04/23. It added 54 new commits
after version 3.0.19.

This version brings a significant number of bug fixes, more than usual
in part thanks to reports from multiple AI-assisted scans that found
bugs in diverse places. A few of these bugs were ranked as major since
they may have stability or even security impacts depending on configs
and deployments:

  - a severe issue was found in the compression library (slz) where
    specially crafted patterns with tune.bufsize above 17408 or
    tune.maxrewrite below 964 (both non-default) could cause output
    buffer overflows due to the overhead exceeding the promised
    worst-case growth bound of 5 bytes and reach up to 1/16 of the
    input contents. Given that the compression output is hardly
    controllable, and the canaries at the end of the pools will catch
    this at release time, the risk of exploitation by a hostile server
    is close to zero, however it will cause repeated crashes if such a
    crafted file is present on a server and regularly downloaded. A
    workaround consists in keeping tune.maxrewrite at least 1/16 of
    tune.bufsize or just not changing them since the defaults are safe.
    A CVE was requested two weeks ago for this one, I'll mention it when
    it arrives.

  - HTTP/2 incomplete transfer detection was missing for HEADERS frames
    carrying END_STREAM. When relayed to an HTTP/1.1 server that
    responds before the end of the transfer, this can result in bytes
    of the next request over the same connection to be ignored. Most of
    the time it will cause the connection to be dropped due to an
    unparsable request, but when combined with "http-reuse never", or
    on totally idle servers, the client could expect the second request
    to reuse the same connection and perform a content smuggling attack
    that would allow to pass an unverified request to a server. For
    those who can't upgrade, a temporary workaround is to disable
    HTTP/2 by specifying "alpn http/1.1" on bind lines and adding
    "disable-h2-upgrade" in HTTP frontends. A CVE will be requested for
    this one.

  - HTTP/1.1 bodyless messages announcing a non-null Content-Length did
    not force close mode on the backend, potentially causing
    desynchronisation between HAProxy and the server in conjunction
    with other bugs.

  - FCGI record length truncation with large bufsize (>=65544) could
    enable request smuggling into PHP-FPM since the 16-bit
    content_length field silently truncated to 65535 bytes.

  - an unvalidated SNI name_len field in ClientHello could cause OOB
    heap reads of up to 65KB via XXH3, smp_dup(), and log-format leaks
    on any TCP frontend using req.ssl_sni, possibly causing crashes when
    used.

  - ECDSA JWT signatures with ES256/384/512 could cause a heap overflow
    of ~14 bytes in the DER conversion before verification.

  - a number of CLI commands were mistakenly missing the "admin" level
    check, allowing a non-privileged CLI to run them. This includes
    "tls-keys show/set", "ocsp set/update/show",
    "get/add/del/clear/commit/set map/acl". These commands now cause a
    deprecation warning to be emitted in logs for versions before 3.3,
    and are rejected in 3.3 and above. The fix consists in appending
    "level admin" at the end of the "stats socket" line in the
    configuration.

  - Lua's httpclient headers conversion accepted more than 101 headers
    without bound checking, causing a stack buffer overflow reachable
    from any Lua action/task/service.

  - peers dictionary cache updates accepted an unvalidated entry id as
    array index, allowing OOB heap writes at attacker-controlled
    offsets.

  - a race condition in task scheduling could cause a BUG_ON() when
    task_schedule() sets expire while the task is already running. Very
    rare but reported by users (e.g. server configured with slowstart
    updating its weight at the same moment it goes up).

  - Lua had a use-after-free of HTTP reason strings managed by Lua's GC
    between set_status() and start_response(), potentially leaking
    adjacent information from memory.

  - the regsub sample function could leak ~9-50KB of stale heap data
    when back-reference expansion overflowed the output buffer.

  - SPOE decode_varint() had no iteration cap, allowing pointer
    arithmetic to wrap and dereference memory ~64KB before the
    allocation, causing SIGSEGV or parser confusion.

  - HTTP/1 bodyless responses (HEAD, 204, 304) were subject to a ~200ms
    TCP cork delay because MSG_MORE was unconditionally set when
    inherited from the upper layer. This notably affected H1 frontend
    to H2 backend setups.

  - zero-copy forwarding was not disabled when draining the request
    after an early response, preventing regular receives.

  - HTTP/2 connection liveness checks used conn->owner to decide if a
    connection was dead, which caused premature connection disposal
    when owner was NULL (fully idle connections after the last stream
    left), leading to connections being closed after each stream at low
    loads. Also, a fix introduced in 3.3.5 to report pending errors
    earlier was reverted since no longer necessary after recent HTX
    fixes.

  - the H1 null-chunk emission condition for bodyless messages was
    wrong, with the server-side flag being tested during request
    processing. For example a chunked response to a HEAD request could
    be sent without the null chunk.

  - HTX defrag used an incorrect function to change part of a block
    value when data expanded, causing old block data to become
    inaccessible after the move.

  - in sample expressions, less common HTTP methods (PATCH etc.) are
    represented by both an enum and a string. The string part was not
    handled correctly in sample duplication functions, resulting in
    their contents appearing empty when trying to fetch the method.

  - peers expired entries were trashed later than expected after
    fullresync because tree reordering didn't move them back in past.

  - QUIC had several fixes: incompatible frames now properly close the
    connection with PROTOCOL_VIOLATION instead of being silently
    dropped. QPACK varint decoding is now also limited to 62-bit, and
    had a risk of 1-byte OOB reads on truncated streams, which could
    cause incorrect header decoding.

  - tcpcheck had several minor fixes: the parsing context for error
    reporting would wrongly be reported as server instead of TCP check,
    and using HTTP sample fetch functions would needlessly cause an
    HTTP transaction to be allocate for streams created on these
    proxies.
  
  - H2 protocol error counting was improved: The parsing error counter
    on the connection and on the proxy are now updated. PRIORITY frame
    exclusive bit was properly masked from the stream ID check.

  - "compression direction response" preserved the request flag instead
    of clearing it during parsing, making it impossible to disable
    request compression if it was earlier enabled.
  
  - config: a few argument parsing errors in conditional expressions
    used in ".if" could be misreported and even cause a crash during
    the parsing. Also, a few keywords relying on warnif_misplaced_*
    didn't check the return value and didn't count emitted warnings as
    warnings.

  - abortonclose now only considers client aborts, not stream aborts,
    preventing yielding rules from being interrupted while the client
    still waits.
  
  - the accept() error messages for ENFILE and ENOMEM now print actconn
    instead of global.maxsock which doesn't reflect system limits.
  
  - a stream created from healthchecks was not flagged as a backend
    connection. It doesn't seem to have had impacts, though maybe some
    error counters could have been incorrectly reported.
  
Finally there were also a few very minor fixes such as an extra ']' in
log-format error message, a wrong check in the opentracing group filter
parser, and an adjustment to avoid suspecting uninitialized variable in
code analysis. The rest is a few doc updates, CI and regtest updates.

While I usually suggest to update only if needed, here I would say that
the number of areas covered by fixes is too broad to precisely know if
some affect your usage or not, so please just update your version.

Please find the usual URLs below :
   Site index       : https://www.haproxy.org/
   Documentation    : https://docs.haproxy.org/
   Wiki             : https://github.com/haproxy/wiki/wiki
   Discourse        : https://discourse.haproxy.org/
   Slack channel    : https://slack.haproxy.org/
   Issue tracker    : https://github.com/haproxy/haproxy/issues
   Q&A from devs    : https://github.com/orgs/haproxy/discussions
   Sources          : https://www.haproxy.org/download/3.0/src/
   Git repository   : https://git.haproxy.org/git/haproxy-3.0.git/
   Git Web browsing : https://git.haproxy.org/?p=haproxy-3.0.git
   Changelog        : https://www.haproxy.org/download/3.0/src/CHANGELOG
   Dataplane API    : 
https://github.com/haproxytech/dataplaneapi/releases/latest
   Pending bugs     : https://www.haproxy.org/l/pending-bugs
   Reviewed bugs    : https://www.haproxy.org/l/reviewed-bugs
   Code reports     : https://www.haproxy.org/l/code-reports
   Latest builds    : https://www.haproxy.org/l/dev-packages

Willy
---
Complete changelog :
Amaury Denoyelle (3):
      MINOR: ncbmbuf: improve itbmap_next() code
      BUG/MINOR: quic: close conn on packet reception with incompatible frame
      BUG/MINOR: quic: fix documentation for transport params decoding

Christopher Faulet (17):
      DOC: config: Add missing 'status-code' param for 'http-check expect' 
directive
      DOC: config: Reorder params for 'tcp-check expect' directive
      BUG/MINOR: config: Properly test warnif_misplaced_* return values
      Revert "BUG/MEDIUM: mux-h2: make sure to always report pending errors to 
the stream"
      BUG/MINOR: http-ana: Only consider client abort for abortonclose
      BUG/MINOR: stconn: Always declare the SC created from healthchecks as a 
back SC
      BUG/MINOR: tcpcheck: Remove unexpected flag on tcpcheck rules for httchck 
option
      BUG/MINOR: tcpcheck: Don't enable http_needed when parsing HTTP samples
      BUG/MINOR: tcpcheck: Use tcpcheck context for expressions parsing
      BUG/MEDIUM: mux-h1: Disable 0-copy forwarding when draining the request
      BUG/MEDIUM: samples: Fix handling of SMP_T_METH samples
      BUG/MEDIUM: htx: Fix function used to change part of a block value when 
defrag
      BUG/MEDIUM: htx: Don't count delta twice when block value is replaced
      BUG/MINOR: mux-h1: Fix condition to send null-chunk for bodyless message
      REGTESTS: Never reuse server connection in jwt/jws_verify.vtc
      REGTESTS: Never reuse server connection in 
server/cli_delete_dynamic_server.vtc
      BUG/MEDIUM: mux-h1: Force close mode for bodyless message announcing a C-L

Cody Ohlsen (1):
      BUG/MEDIUM: mux-h1: Don't set MSG_MORE on bodyless responses forwarded to 
client

Egor Shestakov (1):
      BUG/MINOR: sock: adjust accept() error messages for ENFILE and ENOMEM

Emeric Brun (1):
      BUG/MEDIUM: peers: trash of expired entries delayed after fullresync

Frederic Lecaille (1):
      BUG/MINOR: qpack: fix 62-bit overflow and 1-byte OOB reads in decoding

Greg Kroah-Hartman (9):
      BUG/MEDIUM: payload: validate SNI name_len in req.ssl_sni
      BUG/MEDIUM: jwt: fix heap overflow in ECDSA signature DER conversion
      BUG: hlua: fix stack overflow in httpclient headers conversion
      BUG/MINOR: hlua: fix stack overflow in httpclient headers conversion
      BUG/MINOR: peers: fix OOB heap write in dictionary cache update
      BUG/MINOR: spoe: fix pointer arithmetic overflow in spoe_decode_buffer()
      BUG/MINOR: sample: fix info leak in regsub when exp_replace fails
      BUG/MEDIUM: mux-fcgi: prevent record-length truncation with large bufsize
      BUG/MINOR: hlua: fix use-after-free of HTTP reason string

Ilia Shipitsin (1):
      reg-tests/ssl/ssl_dh.vtc: fix syntax error

Miroslav Zagorac (1):
      BUG/MINOR: ot: fixed wrong NULL check in flt_ot_parse_cfg_group()

Olivier Houchard (2):
      BUG/MEDIUM: tasks: Make sure we don't schedule a task already running
      BUG/MINOR: h2: Don't look at the exclusive bit for PRIORITY frame

Tim Duesterhus (1):
      BUG/MINOR: log: Fix error message when using unavailable fetch in logfmt

William Lallemand (7):
      BUG/MEDIUM: ssl/cli: tls-keys commands warn when accessed without admin 
level
      BUG/MEDIUM: ssl/ocsp: ocsp commands warn when accessed without admin level
      BUG/MEDIUM: map/cli: map/acl commands warn when accessed without admin 
level
      REGTESTS: ssl: mark ssl_dh.vtc as broken
      SCRIPTS: build-vtest: allow to set a TMPDIR and a DESTDIR
      CI: VTest build with git clone + cache
      CI: github: only enable OS X on development branches

Willy Tarreau (9):
      SCRIPTS: git-show-backports: list new commits and how to review them with 
-L
      BUG/MINOR: cfgcond: properly set the error pointer on evaluation error
      BUG/MINOR: cfgcond: always set the error string on openssl_version checks
      BUG/MINOR: cfgcond: fail cleanly on missing argument for "feature"
      BUG/MAJOR: slz: always make sure to limit fixed output to less than worst 
case literals
      BUG/MEDIUM: mux-h2: ignore conn->owner when deciding if a connection is 
dead
      BUG/MINOR: mux-h2: count a proto error when rejecting a stream on parsing 
error
      BUG/MINOR: compression: properly disable request when setting response
      BUG/MAJOR: mux-h2: detect incomplete transfers on HEADERS frames as well

---


Reply via email to