Open kfox1111 opened 5 years ago
Hey @kfox1111, do you mean the client-secret
that ends up in the resulting kubeconfig
file? Gangway never sees your real password or credentials, but your client will need the id & secret to auth back to the OIDC.
Once this step is complete the refresh token is then used to update that secret automatically.
My understanding of the OIDC protocol, a client secret for a web service should never be given out. it is a secret only for that web service. If given out, it breaks the trust model of OIDC. For cli's / local gui's, OIDC providers usually have a mechanism to create clients that are hardened and don't have client secrets. Dex supports this model. For example, https://github.com/dexidp/dex/issues/469
Usually a public client can not have a redirectURL other then localhost. A web service should only have a valid redirectURL.
So usually you need to configure dex with 2 different clients. one public, one for the web service like gangway. You authenticate for gangway and then through a trust, you convert the private client's id token to the public one's.
If the client secret you are giving out as part of gangway's process is its own web service client secret, I believe this is a big problem.
I feel like it is a problem to directly expose something called a secret
... but what is the risk? What does the client secret protect? Perhaps this link can help? https://stackoverflow.com/questions/14563155/oauth-2-0-client-id-and-client-secret-exposed-is-it-a-security-issue
4.1.1. Threat: Obtaining Client Secrets
The attacker could try to get access to the secret of a particular
client in order to:
o replay its refresh tokens and authorization "codes", or
o obtain tokens on behalf of the attacked client with the privileges
of that "client_id" acting as an instance of the client.
The resulting impact would be the following:
o Client authentication of access to the authorization server can be
bypassed.
o Stolen refresh tokens or authorization "codes" can be replayed.
Depending on the client category, the following attacks could be
utilized to obtain the client secret.
Attack: Obtain Secret From Source Code or Binary:
This applies for all client types. For open source projects, secrets
can be extracted directly from source code in their public
repositories. Secrets can be extracted from application binaries
just as easily when the published source is not available to the
attacker. Even if an application takes significant measures to
obfuscate secrets in their application distribution, one should
consider that the secret can still be reverse-engineered by anyone
with access to a complete functioning application bundle or binary.
Countermeasures:
o Don't issue secrets to public clients or clients with
inappropriate security policy (Section 5.2.3.1).
o Require user consent for public clients (Section 5.2.3.2).
o Use deployment-specific client secrets (Section 5.2.3.4).
o Revoke client secrets (Section 5.2.3.6).
Any movement on this? A potential security issue so fundamental to the function of this service really should be answered definitively as a problem, or not.
I wonder if it's possible to use the PKCE flow here so that client secrets aren't involved at all? Not sure if the flow allows for that 🤔
NOTE: this client also has the client secret in the config https://github.com/int128/kubelogin ... which still feels wrong, but maybe its a problem with the way OIDC is implemented in kubernetes api server, rather than these "helpers"
Yeah, there still feels like there is a security hole here somewhere.
I think a better long term solution is just around the corner. Keycloak recently added device flow: https://issues.redhat.com/browse/KEYCLOAK-7675. The kubectl client could talk to oidc via device flow, print out a url / qrcode for the user to login at, and then the cli would unblock and continue on with credentials handed to it by the oidc server.
I'm trying to understand the security ramifications of gangway. As I understand it, in oidc, a web client's secret should never be given to a user. But the example screenshots in the repo do just that. How does this work?