mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
BUG/MEDIUM: http-ana: fix crash or wrong header deletion by http-restrict-req-hdr-names
When using `option http-restrict-req-hdr-names delete`, HAproxy may crash or delete wrong header after receiving request containing multiple forbidden characters in single header name; exact behavior depends on number of request headers, number of forbidden characters and position of header containing them. This patch fixes GitHub issue #1822. Must be backported as far as 2.2 (buggy feature got included in 2.2.25, 2.4.18 and 2.5.8).
This commit is contained in:
parent
b29a1dc2f4
commit
4b85a963be
@ -35,6 +35,32 @@ server s5 {
|
|||||||
txresp
|
txresp
|
||||||
} -start
|
} -start
|
||||||
|
|
||||||
|
server s6 {
|
||||||
|
rxreq
|
||||||
|
expect req.http.x_my_hdr_with_lots_of_underscores == <undef>
|
||||||
|
txresp
|
||||||
|
} -start
|
||||||
|
|
||||||
|
server s7 {
|
||||||
|
rxreq
|
||||||
|
expect req.http.x_my_hdr-1 == <undef>
|
||||||
|
expect req.http.x-my-hdr-2 == on
|
||||||
|
txresp
|
||||||
|
} -start
|
||||||
|
|
||||||
|
server s8 {
|
||||||
|
rxreq
|
||||||
|
expect req.http.x-my_hdr-1 == <undef>
|
||||||
|
expect req.http.x-my_hdr-2 == <undef>
|
||||||
|
txresp
|
||||||
|
} -start
|
||||||
|
|
||||||
|
server s9 {
|
||||||
|
rxreq
|
||||||
|
expect req.http.x-my-hdr-with-trailing-underscore_ == <undef>
|
||||||
|
txresp
|
||||||
|
} -start
|
||||||
|
|
||||||
haproxy h1 -conf {
|
haproxy h1 -conf {
|
||||||
defaults
|
defaults
|
||||||
mode http
|
mode http
|
||||||
@ -50,6 +76,10 @@ haproxy h1 -conf {
|
|||||||
use_backend be-fcgi1 if { path /req4 }
|
use_backend be-fcgi1 if { path /req4 }
|
||||||
use_backend be-fcgi2 if { path /req5 }
|
use_backend be-fcgi2 if { path /req5 }
|
||||||
use_backend be-fcgi3 if { path /req6 }
|
use_backend be-fcgi3 if { path /req6 }
|
||||||
|
use_backend be-http4 if { path /req7 }
|
||||||
|
use_backend be-http5 if { path /req8 }
|
||||||
|
use_backend be-http6 if { path /req9 }
|
||||||
|
use_backend be-http7 if { path /req10 }
|
||||||
|
|
||||||
backend be-http1
|
backend be-http1
|
||||||
server s1 ${s1_addr}:${s1_port}
|
server s1 ${s1_addr}:${s1_port}
|
||||||
@ -72,6 +102,22 @@ haproxy h1 -conf {
|
|||||||
backend be-fcgi3
|
backend be-fcgi3
|
||||||
option http-restrict-req-hdr-names reject
|
option http-restrict-req-hdr-names reject
|
||||||
|
|
||||||
|
backend be-http4
|
||||||
|
option http-restrict-req-hdr-names delete
|
||||||
|
server s6 ${s6_addr}:${s6_port}
|
||||||
|
|
||||||
|
backend be-http5
|
||||||
|
option http-restrict-req-hdr-names delete
|
||||||
|
server s7 ${s7_addr}:${s7_port}
|
||||||
|
|
||||||
|
backend be-http6
|
||||||
|
option http-restrict-req-hdr-names delete
|
||||||
|
server s8 ${s8_addr}:${s8_port}
|
||||||
|
|
||||||
|
backend be-http7
|
||||||
|
option http-restrict-req-hdr-names delete
|
||||||
|
server s9 ${s9_addr}:${s9_port}
|
||||||
|
|
||||||
defaults
|
defaults
|
||||||
mode http
|
mode http
|
||||||
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
|
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||||
@ -114,6 +160,22 @@ client c1 -connect ${h1_fe1_sock} {
|
|||||||
txreq -req GET -url /req6 -hdr "X-my_hdr: on"
|
txreq -req GET -url /req6 -hdr "X-my_hdr: on"
|
||||||
rxresp
|
rxresp
|
||||||
expect resp.status == 403
|
expect resp.status == 403
|
||||||
|
|
||||||
|
txreq -req GET -url /req7 -hdr "X_my_hdr_with_lots_of_underscores: on"
|
||||||
|
rxresp
|
||||||
|
expect resp.status == 200
|
||||||
|
|
||||||
|
txreq -req GET -url /req8 -hdr "X_my_hdr-1: on" -hdr "X-my-hdr-2: on"
|
||||||
|
rxresp
|
||||||
|
expect resp.status == 200
|
||||||
|
|
||||||
|
txreq -req GET -url /req9 -hdr "X-my_hdr-1: on" -hdr "X-my_hdr-2: on"
|
||||||
|
rxresp
|
||||||
|
expect resp.status == 200
|
||||||
|
|
||||||
|
txreq -req GET -url /req10 -hdr "X-my-hdr-with-trailing-underscore_: on"
|
||||||
|
rxresp
|
||||||
|
expect resp.status == 200
|
||||||
} -run
|
} -run
|
||||||
|
|
||||||
client c2 -connect ${h1_fe2_sock} {
|
client c2 -connect ${h1_fe2_sock} {
|
||||||
|
@ -2645,17 +2645,21 @@ static enum rule_result http_req_restrict_header_names(struct stream *s, struct
|
|||||||
|
|
||||||
if (type == HTX_BLK_HDR) {
|
if (type == HTX_BLK_HDR) {
|
||||||
struct ist n = htx_get_blk_name(htx, blk);
|
struct ist n = htx_get_blk_name(htx, blk);
|
||||||
int i;
|
int i, end = istlen(n);
|
||||||
|
|
||||||
for (i = 0; i < istlen(n); i++) {
|
for (i = 0; i < end; i++) {
|
||||||
if (!isalnum((unsigned char)n.ptr[i]) && n.ptr[i] != '-') {
|
if (!isalnum((unsigned char)n.ptr[i]) && n.ptr[i] != '-') {
|
||||||
/* Block the request or remove the header */
|
break;
|
||||||
if (px->options2 & PR_O2_RSTRICT_REQ_HDR_NAMES_BLK)
|
|
||||||
goto block;
|
|
||||||
blk = htx_remove_blk(htx, blk);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i < end) {
|
||||||
|
/* Disallowed character found - block the request or remove the header */
|
||||||
|
if (px->options2 & PR_O2_RSTRICT_REQ_HDR_NAMES_BLK)
|
||||||
|
goto block;
|
||||||
|
blk = htx_remove_blk(htx, blk);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type == HTX_BLK_EOH)
|
if (type == HTX_BLK_EOH)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user