From: Olivier Houchard Date: Mon, 22 Jul 2019 15:43:46 +0000 (+0200) Subject: BUG/CRITICAL: http_ana: Fix parsing of malformed cookies which start by a delimiter X-Git-Tag: v2.1-dev2~286 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0f42389772b2303b162e929449a36b33e181c5f;p=thirdparty%2Fhaproxy.git BUG/CRITICAL: http_ana: Fix parsing of malformed cookies which start by a delimiter When client-side or server-side cookies are parsed, HAProxy enters in an infinite loop if a Cookie/Set-Cookie header value starts by a delimiter (a colon or a semicolon). Depending on the operating system, the service may become degraded, unresponsive, or may trigger haproxy's watchdog causing a service stop or automatic restart. To fix this bug, in the loop parsing the attributes, we must be sure to always skip delimiters once the first attribute-value pair was parsed, empty or not. The credit for the fix goes to Olivier. CVE-2019-14241 was assigned to this bug. This patch fixes the Github issue #181. This patch must be backported to 2.0 and 1.9. However, the patch will have to be adapted. --- diff --git a/src/http_ana.c b/src/http_ana.c index a0507a3c1d..3f681c0f59 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -3448,6 +3448,7 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re htx = htxbuf(&req->buf); ctx.blk = NULL; while (http_find_header(htx, ist("Cookie"), &ctx, 1)) { + int is_first = 1; del_from = NULL; /* nothing to be deleted */ preserve_hdr = 0; /* assume we may kill the whole header */ @@ -3505,8 +3506,9 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re /* find att_beg */ att_beg = prev; - if (prev > hdr_beg) + if (!is_first) att_beg++; + is_first = 0; while (att_beg < hdr_end && HTTP_IS_SPHT(*att_beg)) att_beg++; @@ -3848,6 +3850,8 @@ static void http_manage_server_side_cookies(struct stream *s, struct channel *re ctx.blk = NULL; while (1) { + int is_first = 1; + if (!http_find_header(htx, ist("Set-Cookie"), &ctx, 1)) { if (!http_find_header(htx, ist("Set-Cookie2"), &ctx, 1)) break; @@ -3911,8 +3915,9 @@ static void http_manage_server_side_cookies(struct stream *s, struct channel *re /* find att_beg */ att_beg = prev; - if (prev > hdr_beg) + if (!is_first) att_beg++; + is_first = 0; while (att_beg < hdr_end && HTTP_IS_SPHT(*att_beg)) att_beg++;