Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement OAuth 2.0 Authorization Server Metadata - closes #3143 #3147

Merged
merged 1 commit into from
Aug 23, 2024

Conversation

benfrancis
Copy link
Member

@benfrancis benfrancis commented Aug 4, 2024

Closes #3143.

  • Add a well-known controller
  • Implement Authorization Server Metadata
  • Integration tests

Following this implementation, a GET request to /.well-known/oauth-authorization-server will respond with a JSON document which looks like the following...

{
    "issuer": "http://localhost:8080",
    "authorization_endpoint": "http://localhost:8080/oauth/authorize",
    "token_endpoint": "http://localhost:8080/oauth/token",
    "response_types_supported": [
        "code"
    ],
    "scopes_supported": [
        "/things",
        "/things:readwrite"
    ]
}

...with the host set to match the host of the request.

@benfrancis benfrancis marked this pull request as ready for review August 6, 2024 20:39
@benfrancis benfrancis requested a review from tim-hellhake August 6, 2024 20:39
@benfrancis
Copy link
Member Author

@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?

@tim-hellhake
Copy link
Member

@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.

@benfrancis
Copy link
Member Author

@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.

@benfrancis benfrancis merged commit 9cab2bf into WebThingsIO:master Aug 23, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider Implementing OAuth 2.0 Authorization Server Metadata specification
2 participants