Hi, HAProxy 2.4.24 was released on 2023/08/19. It added 62 new commits after version 2.4.23.
This continuing the backports started with 2.8.2, 2.7.10 and 2.6.15. This release addresses a subset of the same issues and brings a few fixes that went into 2.6.13 and whose further backport had been postponed a little bit. 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. - listener: the pause/resume fixes that went into 2.6.13 have now been backported. - logging too large messages to a ring can cause their loss, due to the maxlen parameter not being accurately calculated. - incomplete log server definitions were added to the global list of servers, but freed without be delete from the list, which can cause all sorts of issues and crashes when walking over that list or at deinit() time. - cache: s-maxage couldn't override "max-age=0" as it ought to, according to the standard. - the "namespace" keyword in default-servers was parsed but ignored - the duplicate stick-table name check did not work for tables declared inside peers sections. - 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, CI and cleanup stuff. Older versions will follow, reusing this changelog when it fits. Thanks to all those who reported issues, tested fixes and helped with the backports! 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.4/src/ Git repository : https://git.haproxy.org/git/haproxy-2.4.git/ Git Web browsing : https://git.haproxy.org/?p=haproxy-2.4.git Changelog : https://www.haproxy.org/download/2.4/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 : Aurelien DARRAGON (36): MINOR: proto_uxst: add resume method CLEANUP: listener: function comment typo in stop_listener() BUG/MINOR: listener: null pointer dereference suspected by coverity MINOR: listener/api: add lli hint to listener functions MINOR: listener: add relax_listener() function MINOR: listener: workaround for closing a tiny race between resume_listener() and stopping MINOR: listener: make sure we don't pause/resume bypassed listeners BUG/MEDIUM: listener: fix pause_listener() suspend return value handling BUG/MINOR: listener: fix resume_listener() resume return value handling BUG/MEDIUM: resume from LI_ASSIGNED in default_resume_listener() MINOR: listener: pause_listener() becomes suspend_listener() BUG/MEDIUM: listener/proxy: fix listeners notify for proxy resume MEDIUM: proto_ux: properly suspend named UNIX listeners MINOR: proto_ux: ability to dump ABNS names in error messages MINOR: hlua: add simple hlua reference handling API BUG/MINOR: hlua: fix reference leak in core.register_task() BUG/MINOR: hlua: fix reference leak in hlua_post_init_state() MINOR: hlua: simplify lua locking BUG/MEDIUM: hlua: prevent deadlocks with main lua lock BUG/MINOR: server: inherit from netns in srv_settings_cpy() BUG/MINOR: namespace: missing free in netns_sig_stop() BUG/MINOR: tcp_sample: bc_{dst,src} return IP not INT BUG/MEDIUM: sink: invalid server list in sink_new_from_logsrv() BUG/MINOR: sink: missing sft free in sink_deinit() BUG/MINOR: ring: size warning incorrectly reported as fatal error BUG/MINOR: ring: maxlen warning reported as alert BUG/MINOR: log: LF upsets maxlen for UDP targets MINOR: sink/api: pass explicit maxlen parameter to sink_write() BUG/MEDIUM: log: improper use of logsrv->maxlen for buffer targets BUG/MINOR: log: fix missing name error message in cfg_parse_log_forward() BUG/MINOR: log: fix multiple error paths in cfg_parse_log_forward() BUG/MINOR: log: free errmsg on error in cfg_parse_log_forward() BUG/MINOR: sink: invalid sft free in sink_deinit() BUG/MINOR: sink: fix errors handling in cfg_post_parse_ring() BUG/MINOR: sink/log: properly deinit srv in sink_new_from_logsrv() BUG/MINOR: hlua: hlua_yieldk ctx argument should support pointers Christopher Faulet (6): MINOR: lua: Add a function to get a reference on a table in the stack 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/MEDIUM: listener: Acquire proxy's lock in relax_listener() if necessary BUG/MAJOR: http-ana: Get a fresh trash buffer for each header value replacement Dragan Dosen (1): BUG/MINOR: chunk: fix chunk_appendf() to not write a zero if buffer is full Ilya Shipitsin (1): CI: explicitely highlight VTest result section if there's something Remi Tricot-Le Breton (1): BUG/MINOR: cache: A 'max-age=0' cache-control directive can be overriden by a s-maxage Thierry Fournier (1): BUG/MINOR: config: Remove final '\n' in error messages Tim Duesterhus (2): CLEANUP: Remove unused function hlua_get_top_error_string 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 (11): BUILD: debug: avoid a build warning related to epoll_wait() in debug code 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 REGTESTS: http-rules: add accept-invalid-http-request for normalize-uri tests 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 normalize-uri DOC: clarify the handling of URL fragments in requests BUG/MINOR: http: skip leading zeroes in content-length values firexinghe (1): BUG/MINOR: hlua: add check for lua_newstate ---