HAProxy 2.2.31 was released on 2023/08/19. It added 22 new commits
after version 2.2.30.

This continues the backports started with 2.8.2, 2.7.10, 2.6.15 and
2.4.24. The 2.2 branch is in critical fixes only so it only takes the
most important fixes from the upper branches.

The high severity issues addressed in this version are the following:

  - performing multiple large-header replacements at once can sometimes
    overwrite parts of the contents of the headers if header size is
    increased. This may happen with the "replace-header" action, when the
    buffer gets too fragmented, a temporary one is needed to realign it,
    then they are permutted. But if this happens more than once, the
    allocated temporary buffer could be the one that had just been used,
    where live data will be overwritten but the new ones. This can cause
    garbage to appear in headers, and might possibly trigger some asserts
    depending on the damage and where this passes. This issue was reported
    by Christian Ruppert.

  - the check for invalid characters on content-length header values doesn't
    reject empty headers, which can pass through. And since they don't have
    a value, they're not merged with next ones, so it is possible to pass
    a request that has both an empty content-length and a populated one.
    Such requests are invalid and the vast majority of servers will reject
    them. But there are certainly still a few non-compliant servers that
    will only look at one of them, considering the empty value equals zero
    and be fooled with this. Thus the problem is not as much for mainstream
    users as for those who develop their own HTTP stack or who purposely use
    haproxy to protect a known-vulnerable server, because these ones may be
    at risk. This issue was reported by Ben Kallus of Dartmouth College and
    Narf Industries. A CVE was filed for this one. There is a work-around,
    though: simply rejecting requests containing an empty content-length
    header will do the job:

             http-request deny if { hdr_len(content-length) 0 }

Then there are a bunch of lower severity ones, particularly:

  - the URL fragments (the part that follows '#') are not allowed to be
    sent on the wire, and their handling on the server side has long been
    ambiguous. Historically most servers would trim them, nowadays with
    stronger specification requirements most of them tend to simply reject
    the request as invalid. Till now we did neither of these, so they
    could appear at the end of the "path" sample fetch contents. It can be
    problematic in case path_end is used to route requests. For example,
    a rule doing routing "{ path_end .png .jpg }" to a static server could
    very well match "index.html#.png". The question of how best to proceed
    in this case was asked to other HTTP implementers and the consensus was
    clearly that this should be actively rejected, which is even specifically
    mandated in certain side-protocol specs. A measurement on haproxy.org
    shows that such requests appear at a rate of roughly 1 per million, and
    are either emitted by poorly written crawlers that copy-paste blocks of
    text, or are sent by vulnerability scanners. Thus a check was added for
    this corner case which is now blocked by default. In case anyone would
    discover that they're hosting a bogus application relying on this, this
    can be reverted using "option accept-invalid-http-request". This issue
    was reported by Seth Manesse and Paul Plasil.

  - logging too large messages to a ring can cause their loss, due to the
    maxlen parameter not being accurately calculated.

  - mworker: automatically adjust the master's maxconn to support the
    sockets used to connect to workers.

The rest is of much lower importance or probability, and the usual DOC
and CI stuff. Older versions will follow, reusing this changelog when
it fits.

Thanks to all those who reported issues, tested fixes and helped with the

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
   Sources          : https://www.haproxy.org/download/2.2/src/
   Git repository   : https://git.haproxy.org/git/haproxy-2.2.git/
   Git Web browsing : https://git.haproxy.org/?p=haproxy-2.2.git
   Changelog        : https://www.haproxy.org/download/2.2/src/CHANGELOG
   Dataplane API    : 
   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

Complete changelog :
Aurelien DARRAGON (3):
      BUG/MINOR: server: inherit from netns in srv_settings_cpy()
      BUG/MINOR: namespace: missing free in netns_sig_stop()
      BUG/MINOR: ring: maxlen warning reported as alert

Christopher Faulet (5):
      BUG/MINOR: sample: Fix wrong overflow detection in add/sub conveters
      BUG/MINOR: http: Return the right reason for 302
      BUG/MINOR: h1-htx: Return the right reason for 302 FCGI responses
      BUG/MAJOR: http-ana: Get a fresh trash buffer for each header value 
      MINOR: ist: Add istend() function to return a pointer to the end of the 

Dragan Dosen (1):
      BUG/MINOR: chunk: fix chunk_appendf() to not write a zero if buffer is 

Ilya Shipitsin (1):
      CI: explicitely highlight VTest result section if there's something

Tim Duesterhus (1):
      DOC: Add tune.h2.max-frame-size option to table of contents

William Lallemand (2):
      BUG/MEDIUM: mworker: increase maxsock with each new worker
      DOC: configuration: describe Td in Timing events

Willy Tarreau (9):
      BUG/MAJOR: http: reject any empty content-length header value
      MINOR: ist: add new function ist_find_range() to find a character range
      MINOR: http: add new function http_path_has_forbidden_char()
      MINOR: h2: pass accept-invalid-http-request down the request parser
      BUG/MINOR: h1: do not accept '#' as part of the URI component
      BUG/MINOR: h2: reject more chars from the :path pseudo header
      REGTESTS: http-rules: verify that we block '#' by default for 
      DOC: clarify the handling of URL fragments in requests
      BUG/MINOR: http: skip leading zeroes in content-length values


Reply via email to