From: Willy Tarreau Date: Wed, 4 Nov 2026 15:15:02 +0000 (+0100) Subject: MINOR: http/hardening: implement hardening "reject-content-length-leading-zero" X-Git-Tag: v3.5-dev11~7 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=97bc177f9f3051028913e169f747395dbcf93af9;p=haproxy.git MINOR: http/hardening: implement hardening "reject-content-length-leading-zero" Rejects requests and responses having a Content-Length header field whose value contains a leading zero before a digit. Some client and server applications tend to parse this as an octal value giving a different body size (e.g. "0300" = 192). This can be used in attacks trying to desynchronize a client or server from the rest of the communication, and for example for cache poisionning attacks. These may seldom be seen on legacy applications but not on standard compoennts found on the internet, so it is generally safe to reject them on public facing listeners. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index b1cafe91a..adf73fd7f 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -34578,6 +34578,17 @@ http-hardening [from ] safe and even recommended to delete such trailers from inbound internet requests. + - reject-content-length-leading-zero (inbound request and response) + Rejects requests and responses having a Content-Length header field + whose value contains a leading zero before a digit. Some client and + server applications tend to parse this as an octal value giving a + different body size (e.g. "0300" = 192). This can be used in attacks + trying to desynchronize a client or server from the rest of the + communication, and for example for cache poisionning attacks. These may + seldom be seen on legacy applications but not on standard components + found on the internet, so it is generally safe to reject them on public + facing listeners. + - reject-content-length-with-te (inbound request and response) Rejects requests and responses having both a Content-Length header field and a Transfer-Encoding header field. While these are permitted diff --git a/include/haproxy/http-t.h b/include/haproxy/http-t.h index 66d8ae7e1..d3b3c0b62 100644 --- a/include/haproxy/http-t.h +++ b/include/haproxy/http-t.h @@ -252,6 +252,7 @@ struct http_violation { #define HTTP_HRD_REJ_HDR_FOLD 0x00000200 #define HTTP_HRD_REJ_CTL_IN_HDR 0x00000400 #define HTTP_HRD_REJ_CL_TE 0x00000800 +#define HTTP_HRD_REJ_CL_LEAD_ZERO 0x00001000 /* insert new masks above this line */ #define HTTP_HRD_ALL 0xFFFFFFFF diff --git a/src/http.c b/src/http.c index fa8ffb429..e4b7c4306 100644 --- a/src/http.c +++ b/src/http.c @@ -813,7 +813,10 @@ int http_parse_cont_len_header(struct ist *value, unsigned long long *body_len, if (unlikely(!cl && n > word.ptr)) { /* There was a leading zero before this digit, * let's trim it. + * In strict mode we reject it though. */ + if (http_harden(HTTP_HRD_REJ_CL_LEAD_ZERO)) + goto fail; word.ptr = n; } @@ -1787,6 +1790,7 @@ const struct http_hardening_kw http_hardening_kws[] = { { "reject-header-trailer-folding", HTTP_HRD_REJ_HDR_FOLD, HTTP_DIR_BOTH }, { "reject-ctl-in-header-trailer", HTTP_HRD_REJ_CTL_IN_HDR, HTTP_DIR_BOTH }, { "reject-content-length-with-te", HTTP_HRD_REJ_CL_TE, HTTP_DIR_BOTH }, + { "reject-content-length-leading-zero",HTTP_HRD_REJ_CL_LEAD_ZERO, HTTP_DIR_BOTH }, /* insert new hardening options above this line */ { "all", HTTP_HRD_ALL, HTTP_DIR_BOTH }, { NULL, 0 }