-
Notifications
You must be signed in to change notification settings - Fork 84
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
Static redirect URIs required by OIDC specification #140
Comments
I was going to open a ticket but I see there is already an existing ticket. The Google OP requires a static redirectURI and does not allow wildcards. Google does let you wildcard localhost ports. The redirect URI This is the error I get when I use SSH3 oidc with google: What is the security goal?Is the security goal of adding a random fragment to securely link the request to the OP with the response form the OP? If so OIDC already provides a more secure way of doing this using PKCE (RFC 7636: Proof Key for Code Exchange). The way it works is client creates: The client then adds VC to the auth request URI. Then to claim the ID Token associated with this request, the client must reveal VC to server. This means that even if an attacker intercepts the original request, the attacker only learns VC not CV. Additionally if the attacker triggers a redirectURI response which is not intended response from the client, when the client-supplies VC, it will break. It looks like SSH3 supports PKCE, but the default in the SSH3 config is to for PKCE to be false.
I don't see a reason why you would ever want PKCE to be false. Is there an OP that doesn't support PKCE? Port diversity with known portsIn OpenPubkey we support choosing a port from a list of ports. This allows parties to add that list of ports to their redirectURI list if needed and also allows us to fail over if another application is already bound to that port. It might be worth copying this pattern to support OPs that don't wildcard localhost ports. |
The random port is also problematic for firewalls |
@almereyda If you want to play around SSH OIDC with a fix redirectURI, I created a PR #144 You can just pull from my branch and use it. |
One reason for using that randomly-generated path was to avoid other programs to hijack the token by sending a fake request to the ssh3 waiting on localhost, causing it to close the socket, and then the attacker could listen on the same port and retrieve the token like that. It seems doable on pretty much any OS. |
@francoismichel If I understand your attack correctly, this was the attack that PKCE was introduced to defeat:
An attacker who intercepts the auth code by listening on the localhost socket can not redeem that auth code for an ID Token because the attacker does not know a value CV such that VC=Hash(CV). This is the value of enabling PKCE. There is another known attack here which neither PKCE nor a randomized redirect URI does not fix.
The user looking at a browser window that popped up has no easy way to determine that this was opened by the legitimate service running on localhost. There two mitigations:
Mobile device flows don't have this problem because app identity is known to the OS and so the iOS can enforce a map of redirect URIs to specific cryptographic identities associated with the candy crush app. There are some other solutions in this space, but using I favor the OpenPubkey cosigner approach. In general it is very hard to protect secrets like this if an attacker has a programming process on your endpoint that can open ports. That can do so much bad stuff, that provided security against such a threat is diminishing returns. |
Why release the port at all? To be the same redirect URL and work best with reverse proxies and firewalls the port should be static anyhow. So I see no reason why the port should be release after using it? |
@septatrix Releasing the port makes sense if you are using this as a cli where the cli isn't always running. The alternative is a daemon which starts at OS bootup and always holds that port or a set of ports, but that is a more complex client to build. |
Ah I was under the assumption that the SSH3 server would be the one receiving the token. That seems like the intuitive solution |
Thanks for the discussion. The reason why PKCE is disabled by default is simply because I couldn't make it to work by the time with that specific version of the oidc module and the google OP, but I may give it another try now. We should probably list the common OPs that support PKCE well and enable it by default. |
Concerning the random URL, I am not strongly against removing it, but we should probably ensure that PKCE is enabled then, and use the random URL if not. |
I would also like to note that the RFC says to construct these loopback URLs using the numeric literals (127.0.0.1 and [::1] respectively) instead of "localhost". Another option (which would also be necessary when one wants to implement a mobile client for SSH3) is to use private-use URI schemes like |
@septatrix My two cents:
|
In Linux binding to ::1 defaults to dual stack mode, i.e. it also received IPv4 packets
Not really sure about this TBH |
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.ssh3/auth/openid_connect.go
Lines 46 to 56 in 20f2894
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:
$(openssl rand -hex 32)
, is generated by the identity provider, e.g.6f1379417c8a5cae738bc030e5ddc59ec352af02704351e182727fb0136fe1fe
gloas-$(openssl rand -hex 32)
, is generated in the identity provider, here GitLab, e.g.gloas-48ac71b03fcf805a127ba614c88646956751e154c76b77991f909a918c21b86e
http://localhost/
openid
,email
Notes:
localhost
. Then PKCE authentication is required.ssh3/auth/openid_connect.go
Line 68 in 20f2894
Server configuration:
Client configuration:
The SSH3 server has been started first with
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:ssh3-server --bind '[::]:8443' -cert ~/ssh3-cert.pem -key ~/ssh3-priv.key -v
When spawning an associated SSH3 client with
ssh3 -use-oidc https://gitlab.example.com -v server:8443/ssh3-term
the OIDC provider, here GitLab, responds with:
This also happens when using the PKCE authentication scheme:
ssh3 -use-oidc https://gitlab.example.com -do-pkce -v server:8443/ssh3-term
Primary ways of mitigating this could be:
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:
The text was updated successfully, but these errors were encountered: