francoismichel / francoismichel/ssh3
Static redirect URIs required by OIDC specification
- Dominant language
- Go
- Stars
- 5k
- Forks
- 118
- PR merge metrics
- No merged PRs in 30d
Description
The current implementation of the OIDC client in the `ssh3` client binary spawns a local HTTP webserver at a random port with a random URL path fragment. This contradicts the OIDC specification, which expects a persistent and static (list of) redirect URI(s), even when the application is set to confidential.
https://github.com/francoismichel/ssh3/blob/20f2894426742ee2fe92e33fa3d2521be7677b20/auth/openid_connect.go#L46-L56
- https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadatahttps://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
> [3.1.2.1. Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest)
> redirect_uri
> REQUIRED. Redirection URI to which the response will be sent. This URI MUST exactly match one of the Redirection URI values for the Client pre-registered at the OpenID Provider, with the matching performed as described in [Section 6.2.1 of [RFC3986] (Simple String Comparison)](https://www.rfc-editor.org/rfc/rfc3986.html#section-6.2.1). When using this flow, the Redirection URI SHOULD use the https scheme; however, it MAY use the http scheme, provided that the Client Type is confidential, as defined in Section 2.1 of OAuth 2.0, and provided the OP allows the use of http Redirection URIs in this case. Also, if the Client is a native application, it MAY use the http scheme with localhost or the IP loopback literals 127.0.0.1 or [::1] as the hostname. The Redirection URI MAY use an alternate scheme, such as one that is intended to identify a callback into a native application.
This way it is not possible to set up an OIDC client application with an ID and secret pair that works, e.g. with GitLab.
OIDC Provider:
- Application ID: `$(openssl rand -hex 32)`, is generated by the identity provider, e.g. `6f1379417c8a5cae738bc030e5ddc59ec352af02704351e182727fb0136fe1fe`
- Secret: `gloas-$(openssl rand -hex 32)`, is generated in the identity provider, here GitLab, e.g. `gloas-48ac71b03fcf805a127ba614c88646956751e154c76b77991f909a918c21b86e`
- Callback URL: `http://localhost/`
- Trusted: No
- Confidential: Yes
- Scopes: `openid`, `email`
Notes:
- Confidential can also be set to No, since we are serving the redirect URI from `localhost`. Then PKCE authentication is required.
- The scopes must be matching with what is requested by the client:
https://github.com/francoismichel/ssh3/blob/20f2894426742ee2fe92e33fa3d2521be7677b20/auth/openid_connect.go#L68
Server configuration:
~/.ssh3/authorized_identities
```
oidc 6f1379417c8a5cae738bc030e5ddc59ec352af02704351e182727fb0136fe1fe https://gitlab.example.com user@example.com
```
Client configuration:
~/.ssh3/oidc_config.json
```json
[
{
"issuer_url": "https://gitlab.example.com",
"client_id": "", // e.g. 6f1379417c8a5cae738bc030e5ddc59ec352af02704351e182727fb0136fe1fe
"client_secret": "" // e.g. gloas-48ac71b03fcf805a127ba614c88646956751e154c76b77991f909a918c21b86e
}
]
```
> *Note:* The Readme speaks of `config.json` and also `oidc_config.json`, while the latter is the default when *not* using the `-oidc-config` flag.
>
> https://github.com/francoismichel/ssh3/blob/20f2894426742ee2fe92e33fa3d2521be7677b20/README.md?plain=1#L262
>
> https://github.com/francoismichel/ssh3/blob/20f2894426742ee2fe92e33fa3d2521be7677b20/cmd/ssh3.go#L454
The SSH3 server has been started first with
```console
ssh3-server --bind '[::]:8443' -cert ~/ssh3-cert.pem -key ~/ssh3-priv.key -generate-selfsigned-cert -v
```
to generate the key pair.
Subsequent invocations fail, when the `-generate-selfsigned-cert` flag is passed, why the final command line reads:
```console
ssh3-server --bind '[::]:8443' -cert ~/ssh3-cert.pem -key ~/ssh3-priv.key -v
```
When spawning an associated SSH3 client with
```console
ssh3 -use-oidc https://gitlab.example.com -v server:8443/ssh3-term
```
the OIDC provider, here GitLab, responds with:
> ## An error has occurred
>
> ```
> The redirect URI included is not valid.
> ```
This also happens when using the PKCE authentication scheme:
```console
ssh3 -use-oidc https://gitlab.example.com -do-pkce -v server:8443/ssh3-term
```
Primary ways of mitigating this could be:
- [ ] Supporting the dynamic client registration protocol: [Final: OpenID Connect Dynamic Client Registration 1.0 incorporating errata set 2](https://openid.net/specs/openid-connect-registration-1_0.html)
- [ ] Using a static redirect URI on the client which can be preconfigured in the OIDC provider, e.g. by a convention for port and secret, or by allowing to configure them directly.
- [ ] Providing a complete example in the documentation or in the Readme that explains the whole life cycle of setting up and configuring OIDC-based SSH3 logins at the Identity Provider (IdP; OIDC provider), in the SSH3 server and in the SSH3 client.
Additionally there may be a way to get rid of the `client_secret` on the client in case of only supporting PKCE authentication for non-confidential OIDC clients, e.g. by introducing a flat `-require-pkce` on the server.
References:
- #99
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with auth/openid_connect.go at the redirect-server setup and cmd/ssh3.go around the OIDC configuration flags; read the linked README section for current configuration behavior. The issue lists several possible mitigations, so first establish which approach is intended. Done means the selected approach supports provider-registered redirect URIs and its setup is documented and verifiable with the described GitLab flow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- authentication, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100