Tim, Thank you for your reply.
Your code sends a 421 if the SNI and host header don't match. Is this the recommended behavior? The RFC is pretty thin here: " Since it is possible for a client to present a different server_name in the application protocol, application server implementations that rely upon these names being the same MUST check to make sure the client did not present a different name in the application protocol." (from https://datatracker.ietf.org/doc/html/rfc6066#section-11.1 ) My initial idea was to simply pave over any incoming headers with the SNI: > http-request set-header Host %[ssl_fc_sni] if { ssl_fc_has_sni } This wouldn't abort the request with a 421 but I am not sure if I MUST abort it to be compliant. Regarding domain fronting, I thought I might be able to have the cake and eat it, too if I still allowed it but only prevented it for mTLS Requests. Maybe like this: > http-request set-header Host %[ssl_fc_sni] if { ssl_c_used } What are your thoughts? Best regards, Dom On 24.06.21, 16:05, "Tim Düsterhus" <t...@bastelstu.be> wrote: Dominik, On 6/24/21 3:29 PM, Froehlich, Dominik wrote: > Not sure if you would call this a security issue, hence I am asking this on the mailing list prior to opening a github issue: This is also known as "Domain Fronting" (https://en.wikipedia.org/wiki/Domain_fronting). It's not necessarily a security issue and in fact might be the desired behavior in certain circumstances. > I’ve noticed that it is really easy to bypass the check on client certificates of a domain when the client can present a valid certificate for another domain. Indeed. I also use client certificates for authentication and I'm aware of this issue. That's why I validate that the SNI and Host match up for my set up. In fact I added the 'strcmp' converter to HAProxy just for this purpose. The documentation for 'strcmp' also gives an explicit example on how to use it to prevent domain fronting: > http-request set-var(txn.host) hdr(host) > # Check whether the client is attempting domain fronting. > acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0 https://cbonte.github.io/haproxy-dconv/2.4/configuration.html#7.3.1-strcmp My full rules look like this: > # Verify that SNI and Host header match > http-request set-var(txn.host) hdr(host) > http-request deny deny_status 400 unless { req.hdr_cnt(host) eq 1 } > http-request deny deny_status 421 unless { ssl_fc_sni,strcmp(txn.host) eq 0 } - > […] > > My questions: > > * HAproxy does seem to treat SNI (L5) and HTTP Host Header (L7) as unrelated. Is this true? Yes. > * Applications offloading TLS to HAproxy usually trust that mTLS requests coming in are validated correctly. They usually don’t revalidate the entire certificate again and only check for the subject’s identity. Is there a way to make SNI vs host header checking more strict? Yes, see above. > * What’s the best practice to dispatch mTLS requests to backends? I’ve used a host header based approach here but it shows the above vulnerabilities. You *must* use the 'Host' header for routing. Using the SNI value for routing is even more unsafe. But you also must validate that the SNI matches up or that the client presented a valid certificate. Best regards Tim Düsterhus