mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-24 21:52:17 +00:00
7ef244d73b
This test ensure that h2 pseudo headers are properly checked for invalid characters and the host header is ignored if :authority is present. This is necessary to prevent h2 desync attacks as described here https://portswigger.net/research/http2
168 lines
2.8 KiB
Plaintext
168 lines
2.8 KiB
Plaintext
# This test ensures that h2 requests with invalid pseudo-headers are properly
|
|
# rejected. Also, the host header must be ignored if authority is present. This
|
|
# is necessary to avoid http/2 desync attacks through haproxy as described here
|
|
# https://portswigger.net/research/http2
|
|
|
|
varnishtest "h2 desync attacks"
|
|
feature ignore_unknown_macro
|
|
|
|
server s1 {
|
|
rxreq
|
|
expect req.http.host == "hostname"
|
|
txresp
|
|
} -start
|
|
|
|
# haproxy frontend
|
|
haproxy hap -conf {
|
|
defaults
|
|
mode http
|
|
|
|
listen feSrvH1
|
|
bind "fd@${feSrvH1}"
|
|
http-request return status 200
|
|
|
|
listen feSrvH2
|
|
bind "fd@${feSrvH2}" proto h2
|
|
http-request return status 200
|
|
|
|
listen fe1
|
|
bind "fd@${fe1}" proto h2
|
|
server srv-hapSrv "${hap_feSrvH1_addr}:${hap_feSrvH1_port}"
|
|
|
|
listen fe2
|
|
bind "fd@${fe2}" proto h2
|
|
server srv-hapSrv "${hap_feSrvH2_addr}:${hap_feSrvH2_port}" proto h2
|
|
|
|
listen fe3
|
|
bind "fd@${fe3}" proto h2
|
|
server s1 "${s1_addr}:${s1_port}"
|
|
} -start
|
|
|
|
# valid request
|
|
client c1 -connect ${hap_fe1_sock} {
|
|
txpri
|
|
stream 0 {
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
txreq \
|
|
-method "GET" \
|
|
-scheme "http" \
|
|
-url "/"
|
|
rxresp
|
|
expect resp.status == 200
|
|
} -run
|
|
} -run
|
|
|
|
# valid request
|
|
client c2 -connect ${hap_fe2_sock} {
|
|
txpri
|
|
stream 0 {
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
txreq \
|
|
-method "GET" \
|
|
-scheme "http" \
|
|
-url "/"
|
|
rxresp
|
|
expect resp.status == 200
|
|
} -run
|
|
} -run
|
|
|
|
# invalid path
|
|
client c3-path -connect ${hap_fe1_sock} {
|
|
txpri
|
|
stream 0 {
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
txreq \
|
|
-method "GET" \
|
|
-scheme "http" \
|
|
-url "hello-world"
|
|
rxrst
|
|
} -run
|
|
} -run
|
|
|
|
# invalid scheme
|
|
client c4-scheme -connect ${hap_fe1_sock} {
|
|
txpri
|
|
stream 0 {
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
txreq \
|
|
-method "GET" \
|
|
-scheme "http://localhost/?" \
|
|
-url "/"
|
|
rxresp
|
|
expect resp.status == 400
|
|
} -run
|
|
} -run
|
|
|
|
# invalid method
|
|
client c5-method -connect ${hap_fe2_sock} {
|
|
txpri
|
|
stream 0 {
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
txreq \
|
|
-method "GET?" \
|
|
-scheme "http" \
|
|
-url "/"
|
|
rxresp
|
|
expect resp.status == 400
|
|
} -run
|
|
} -run
|
|
|
|
# different authority and host headers
|
|
# in this case, host should be ignored in favor of the authority
|
|
client c6-host-authority -connect ${hap_fe3_sock} {
|
|
txpri
|
|
stream 0 {
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
txreq \
|
|
-method "GET" \
|
|
-scheme "http" \
|
|
-url "/" \
|
|
-hdr ":authority" "hostname" \
|
|
-hdr "host" "other_host"
|
|
} -run
|
|
} -run
|
|
|
|
server s1 -wait
|