blob: 112bc60a4c426303814e2f062a772bbcc09e67f5 [file] [log] [blame]
Amaury Denoyelle39faba72021-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
9server s1 {
10 rxreq
11 expect req.http.host == "hostname"
12 txresp
13} -start
14
15# haproxy frontend
16haproxy hap -conf {
17 defaults
18 mode http
19
20 listen feSrvH1
21 bind "fd@${feSrvH1}"
22 http-request return status 200
23
24 listen feSrvH2
25 bind "fd@${feSrvH2}" proto h2
26 http-request return status 200
27
28 listen fe1
29 bind "fd@${fe1}" proto h2
30 server srv-hapSrv "${hap_feSrvH1_addr}:${hap_feSrvH1_port}"
31
32 listen fe2
33 bind "fd@${fe2}" proto h2
34 server srv-hapSrv "${hap_feSrvH2_addr}:${hap_feSrvH2_port}" proto h2
35
36 listen fe3
37 bind "fd@${fe3}" proto h2
38 server s1 "${s1_addr}:${s1_port}"
39} -start
40
41# valid request
42client c1 -connect ${hap_fe1_sock} {
43 txpri
44 stream 0 {
45 txsettings
46 rxsettings
47 txsettings -ack
48 rxsettings
49 expect settings.ack == true
50 } -run
51
52 stream 1 {
53 txreq \
54 -method "GET" \
55 -scheme "http" \
56 -url "/"
57 rxresp
58 expect resp.status == 200
59 } -run
60} -run
61
62# valid request
63client c2 -connect ${hap_fe2_sock} {
64 txpri
65 stream 0 {
66 txsettings
67 rxsettings
68 txsettings -ack
69 rxsettings
70 expect settings.ack == true
71 } -run
72
73 stream 1 {
74 txreq \
75 -method "GET" \
76 -scheme "http" \
77 -url "/"
78 rxresp
79 expect resp.status == 200
80 } -run
81} -run
82
83# invalid path
84client c3-path -connect ${hap_fe1_sock} {
85 txpri
86 stream 0 {
87 txsettings
88 rxsettings
89 txsettings -ack
90 rxsettings
91 expect settings.ack == true
92 } -run
93
94 stream 1 {
95 txreq \
96 -method "GET" \
97 -scheme "http" \
98 -url "hello-world"
99 rxrst
100 } -run
101} -run
102
103# invalid scheme
104client c4-scheme -connect ${hap_fe1_sock} {
105 txpri
106 stream 0 {
107 txsettings
108 rxsettings
109 txsettings -ack
110 rxsettings
111 expect settings.ack == true
112 } -run
113
114 stream 1 {
115 txreq \
116 -method "GET" \
117 -scheme "http://localhost/?" \
118 -url "/"
119 rxresp
120 expect resp.status == 400
121 } -run
122} -run
123
124# invalid method
125client c5-method -connect ${hap_fe2_sock} {
126 txpri
127 stream 0 {
128 txsettings
129 rxsettings
130 txsettings -ack
131 rxsettings
132 expect settings.ack == true
133 } -run
134
135 stream 1 {
136 txreq \
137 -method "GET?" \
138 -scheme "http" \
139 -url "/"
140 rxresp
141 expect resp.status == 400
142 } -run
143} -run
144
145# different authority and host headers
146# in this case, host should be ignored in favor of the authority
147client c6-host-authority -connect ${hap_fe3_sock} {
148 txpri
149 stream 0 {
150 txsettings
151 rxsettings
152 txsettings -ack
153 rxsettings
154 expect settings.ack == true
155 } -run
156
157 stream 1 {
158 txreq \
159 -method "GET" \
160 -scheme "http" \
161 -url "/" \
162 -hdr ":authority" "hostname" \
163 -hdr "host" "other_host"
164 } -run
165} -run
166
167server s1 -wait