blob: 997b11bf1ce10a3ac622a0c4ff321528c261ccec [file] [log] [blame]
Amaury Denoyelleb9e34f72021-08-13 09:43:24 +02001# This test ensures that h2 requests with invalid pseudo-headers are properly
2# rejected. Also, the host header must be ignored if authority is present. This
3# is necessary to avoid http/2 desync attacks through haproxy as described here
4# https://portswigger.net/research/http2
5
6varnishtest "h2 desync attacks"
7feature ignore_unknown_macro
8
9# haproxy frontend
10haproxy hap -conf {
11 defaults
12 mode http
13
14 listen feSrvH1
15 bind "fd@${feSrvH1}"
16 http-request redirect location h1=%[req.hdr(host)]
17
18 listen feSrvH2
19 bind "fd@${feSrvH2}" proto h2
20 http-request redirect location h2=%[req.hdr(host)]
21
22 listen fe1
23 bind "fd@${fe1}" proto h2
24 server srv-hapSrv "${hap_feSrvH1_addr}:${hap_feSrvH1_port}"
25
26 listen fe2
27 bind "fd@${fe2}" proto h2
28 server srv-hapSrv "${hap_feSrvH2_addr}:${hap_feSrvH2_port}" proto h2
29
30 listen fe3
31 bind "fd@${fe3}" proto h2
32 server s1 "${s1_addr}:${s1_port}"
33} -start
34
35# valid request
36client c1 -connect ${hap_fe1_sock} {
37 txpri
38 stream 0 {
39 txsettings
40 rxsettings
41 txsettings -ack
42 rxsettings
43 expect settings.ack == true
44 } -run
45
46 stream 1 {
47 txreq \
48 -method "GET" \
49 -scheme "http" \
50 -url "/"
51 rxresp
52 expect resp.status == 302
53 } -run
54} -run
55
56# valid request
57client c2 -connect ${hap_fe2_sock} {
58 txpri
59 stream 0 {
60 txsettings
61 rxsettings
62 txsettings -ack
63 rxsettings
64 expect settings.ack == true
65 } -run
66
67 stream 1 {
68 txreq \
69 -method "GET" \
70 -scheme "http" \
71 -url "/"
72 rxresp
73 expect resp.status == 302
74 } -run
75} -run
76
77# invalid path
78client c3-path -connect ${hap_fe1_sock} {
79 txpri
80 stream 0 {
81 txsettings
82 rxsettings
83 txsettings -ack
84 rxsettings
85 expect settings.ack == true
86 } -run
87
88 stream 1 {
89 txreq \
90 -method "GET" \
91 -scheme "http" \
92 -url ".hello-world" \
93 -hdr "host" "original-host"
94 rxresp
95 expect resp.status == 302
96 expect resp.http.Location ~ original-host
97 } -run
98} -run
99
100# invalid scheme
101client c4-scheme -connect ${hap_fe1_sock} {
102 txpri
103 stream 0 {
104 txsettings
105 rxsettings
106 txsettings -ack
107 rxsettings
108 expect settings.ack == true
109 } -run
110
111 stream 1 {
112 txreq \
113 -method "GET" \
114 -scheme "http://localhost/?" \
115 -url "/" \
116 -hdr "host" "original-host"
117 rxresp
118 expect resp.status == 302
119 expect resp.http.Location ~ original-host
120 } -run
121} -run
122
123# invalid method
124client c5-method -connect ${hap_fe2_sock} {
125 txpri
126 stream 0 {
127 txsettings
128 rxsettings
129 txsettings -ack
130 rxsettings
131 expect settings.ack == true
132 } -run
133
134 stream 1 {
135 txreq \
136 -method "GET?" \
137 -scheme "http" \
138 -url "/"
139 rxresp
140 expect resp.status == 400
141 } -run
142} -run