Closed benfrancis closed 3 months ago
@tim-hellhake One concern I have with this implementation is that because a gateway may be served via multiple host names (e.g. foo.webthings.io or gateway.local or mydomain.com) it currently takes the host from the Host
header in an HTTP request. I wonder if this might be vulnerable to a host header injection attack.
If so, is there a better way to determine the host the gateway is being served on? What if there are more than one or a custom static or dynamic DNS setup is in place?
@benfrancis
One concern I have with this implementation is that because a gateway may be served via multiple host names (e.g. foo.webthings.io or gateway.local or mydomain.com) it currently takes the host from the Host header in an HTTP request. I wonder if this might be vulnerable to a host header injection attack.
Technically, yes, but what's the point of fooling yourself?
Usually, the attacker fakes the Host
header to trick the server into doing things it shouldn't.
Since the server does not rely on the Host
header, the attacker is the only one affected.
There is one thing, though... If a proxy caches the request, the attacker might be possible to poison the cache to lure users to a malicious server.
Keycloak, a pretty mature authorization server, also relies on the host header.
The key is to pin the hostname via the config parameter or configure the reverse proxy to override the Host
header so that you can trust it.
The best way to mitigate this attack vector is to allow only localhost
or the configured tunnel hostname.
It would also be nice to allow the user to configure the hostname to support custom setups.
If so, is there a better way to determine the host the gateway is being served on? What if there are more than one or a custom static or dynamic DNS setup is in place?
I don't see a way to achieve this without knowing the exact user setup.
@tim-hellhake Thank you for the feedback. Let's look at providing a way to statically configure the canonical domain of the gateway rather than deriving it dynamically from a Host header in the future. I note there are other places in the codebase where we currently use the Host header too. This could be part of #82.
Closes #3143.
Following this implementation, a
GET
request to/.well-known/oauth-authorization-server
will respond with a JSON document which looks like the following......with the host set to match the host of the request.