From b743b566b4215ed49b95d2fc22054ffe66202a0f Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 28 Apr 2026 09:37:34 +0200 Subject: [PATCH] BUG/MAJOR: http: forbid comma character in authority value Strictly speaking, the comma character in authority is allowed by RFC3986. However, it is pretty ambiguous for Host header value because comma is also the value separator for headers supporting multiple value. It is also very unlikely to have comma in host header value or authority. So instead of dealing with this case with all the risks of bugs that this entails, we've decided to forbid the comma in authority and host header value during the parsing. Concretely, only http_authority_has_forbidden_char() was updated. The internal API was not updated to prevent comma to be inserted when the host header value is updated for instance. But this should be so uncommon that it is not really a concern. This patch should be backported as far as 2.8. For previous verions, http_authority_has_forbidden_char() function does not exist. --- include/haproxy/http.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/haproxy/http.h b/include/haproxy/http.h index ea7890537..aa20f5e16 100644 --- a/include/haproxy/http.h +++ b/include/haproxy/http.h @@ -238,6 +238,11 @@ static inline int http_path_has_forbidden_char(const struct ist ist, const char * fall back to the slow path and decide. Brackets are used for IP-literal and * deserve special case, that is better handled in the slow path. The function * returns 0 if no forbidden char is presnet, non-zero otherwise. + * + * There is a special case for the comma (','). While it is allowed, we reject + * it because the authority is higly linked with the host header. The comma is + * also the header value separator. So it is highly ambiguous to use it for the + * authority/host value. */ static inline int http_authority_has_forbidden_char(const struct ist ist) { @@ -257,6 +262,7 @@ static inline int http_authority_has_forbidden_char(const struct ist ist) c = p[ofs]; if (unlikely(c < 0x21 || c > 0x7e || + c == ',' || /* Special case: forbidden because it is ambiguous for the host header value */ c == '#' || c == '/' || c == '?' || c == '@' || c == '[' || c == '\\' || c == ']')) { /* all of them must be rejected, except '[' which may