As an example, let's look at how authentication works with Kubernetes:
Specifically, let's focus on what the api server does. To authenticate the request, it:
- Verifies that the JWT signature is valid
- Checks that the JWT isn't expired
- Checks that this user is authorized to use this API
There must be more to it than this! The thing about OIDC providers is they will hand out tokens with valid signatures to just about anyone. For example let's say I want to use Google as my identity provider. If the only requirement were that the JWT signature is valid, an attacker could set up some site I might like, say with funny cat pictures. At some point I visit the site and log in, and bingo, attacker has an identity JWT with a valid signature and my name on it. It would be Pretty Bad if the owner of funnycatpictures.com could now access the Kubernetes API server under my name.
So what specifically are the constraints that prevent this attack?
My understanding is the
aud (audience) claim in the JWT is part of it: Kubernetes must accept the token only if
aud contains its OAuth client ID. This should mean tokens issued to other OAuth clients (like the funny cat pictures site) won't be accepted because they will have the wrong
However, there seems to be a way around this with the implicit grant flow, which doesn't require an OAuth client secret. As such, funnycatpictures.com could use the implicit flow but with the Kubernetes client id, thus obtaining tokens with the correct
aud which would be accepted by the Kubernetes API server.
What prevents such an attack?