From: Greg Kroah-Hartman Date: Tue, 7 Apr 2026 07:48:08 +0000 (+0200) Subject: BUG/MEDIUM: payload: validate SNI name_len in req.ssl_sni X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ed267f9bc541d5b0bb18b994e9336ba9d98927b5;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: payload: validate SNI name_len in req.ssl_sni The 16-bit name_len field is read directly from the ClientHello and stored as the sample length without any validation against srv_len, ext_len, or the channel buffer size. A 65-byte ClientHello with name_len=0xffff produces a sample claiming 65535 bytes of data when only ~4 bytes are actually present in the buffer. Downstream consumers then read tens of kilobytes past the channel buffer: - pattern.c:741 XXH3() hashes 65535 bytes -> ~50KB OOB heap read - sample.c smp_dup memcpy if large trash configured - log-format %[req.ssl_sni] leaks heap contents to logs/headers Reachable pre-authentication on any TCP frontend using req.ssl_sni (req_ssl_sni), which is the documented way to do SNI-based content switching in TCP mode. No SSL handshake is required; the parser runs on raw buffer contents in tcp-request content rules. Bug introduced in commit d4c33c8889ec3 (2013). The ALPN parser in the same file at line 1044 has the equivalent check; SNI never did. This must be backported to all supported versions. --- diff --git a/src/payload.c b/src/payload.c index e1a158355..77734e0f1 100644 --- a/src/payload.c +++ b/src/payload.c @@ -874,6 +874,9 @@ smp_fetch_ssl_hello_sni(const struct arg *args, struct sample *smp, const char * name_type = data[6]; name_len = (data[7] << 8) + data[8]; + if (name_len + 3 > srv_len) + goto not_ssl_hello; + if (name_type == 0) { /* hostname */ smp->data.type = SMP_T_STR; smp->data.u.str.area = (char *)data + 9;