I’m doing the following to redirect non-https traffic to https:
redirect scheme https code 301 if !{ ssl_fc }
Which works great, however if a user injects a Host
header they are redirected to that URI rather than the target.
E.g.
Request: http://example.com
Host Header: maliciousexample.com
Expected:
Redirect to https://example.com
Actual:
Redirect to https://maliciousexample.com
Is it possible to replace the Host
header with the target URI or failing that, check that the Host
header is a domain I have configured?
Use redirect prefix:
redirect prefix https://example.com if !{ ssl_fc }
Thanks - is there a nice way to do this if I have many domains configured?
acl host_server_a hdr(host) -i example.com
acl host_server_a hdr(host) -i example1.com
acl host_server_b hdr(host) -i example2.com
acl host_server_c hdr(host) -i example3.com
I don’t know what the rest of your configuration looks like or what attack vectors you have in mind.
If you don’t want to respond to malicious host headers, actually deny them as opposed to restrict the http redirect:
http-request allow host_server_a or host_server_b or host_server_c
http-request deny
or
http-request allow host_server_a
http-request allow host_server_b
http-request allow host_server_c
http-request deny
You can also put the list of domains in a file. Read section 7 of the docs:
http://docs.haproxy.org/2.6/configuration.html#7
Then once you passed the host header check, redirect it all to https:
redirect scheme https code 301 if !{ ssl_fc }
Thanks @lukastribus
Ended up doing a list of domains in a file:
http-request allow if { hdr_beg(host) -f /etc/haproxy/domains.cfg }
http-request deny
redirect scheme https code 301 if !{ ssl_fc }