Description
Another issue to have come out of the discussion on #2288 is that of how hostname matches are performed when traffic matchin on HTTPRoutes when those HTTPRoutes are attached to a Listener that is terminating HTTPS.
When that is happening, there are at least two places where the hostname can be matched - the SNI (Server Name Indicator) that's used as part of the TLS negotiation, and the Host:
header that's handled as part of the HTTP request.
It's both not immediately obvious and critically important for TLS security that Gateway API implementations enforce that the SNI and the Host
header match, using the usual hostname matching rules.
This is really important once we add external client certificate validation (as in #2273). If we don't mandate that the SNI and Host
header match, then it's possible to bypass client certificate validation by adding another hostname to the same Gateway implementation, using that as the SNI, and then specifying the secure hostname as the Host
header.
An example:
We have a secure listener on secure.example.com
- this Listener requires a client certificate to authenticate external clients, and uses a HTTPRoute that forwards to the secure
backend.
However, if I also add an insecure.example.com
Listener that also requires TLS, but when performing the actual HTTP request, we send an SNI of insecure.example.com
and a Host
header of secure.example.com
, then it's possible to bypass the client certificate requirement, through no fault of the owner of the secure
backend.
To address this, I propose the following rules:
(in this part, for simplicity, I'm only going to discuss as though the hostname
is set as the Listener level, but remember that there is a hostname
-matching part of HTTPRoute attachment that can complicate this further).
That is:
- if the Listener
hostname
is precise -cafe.example.com
, then both the SNI andHost
header must be equal tocafe.example.com
. - If the Listener
hostname
is precise -*.example.com
, then both the SNI andHost
header must still be the same value. For example, bothcafe.example.com
andstoreroom.example.com
are valid matches, but in either case, both the SNI andHost
header must be set to the same value.
If the SNI and Host
header are not exactly equal, then the request must be rejected (the exact error code I'm not sure on at the moment, but probably something in the 4xx range, since it's a property of the user request.)