3 ms·
This complexity is a security nightmare. I write SPAs. I use Keycloak OIDC as the authentication layer. I have the SPA set up as a client using the 'Standard F
by RandomBK 3y ago
This complexity is a security nightmare.
I write SPAs. I use Keycloak OIDC as the authentication layer. I have the SPA set up as a client using the 'Standard Flow' with no Client Authentication[0]. I've carefully set my valid redirect URIs. I use the official Keycloak JS client and the standard JWT authentication implementation in my API server.
To this day I still have no idea if I'm doing everything correctly. I guess I'll have to eventually hire some expensive security consultant to go over everything, but every step of this setup is filled with hidden gotchas:
* There's multiple overlapping standards, each with a dozen different variants. The Keycloak OIDC config refers to OAuth2 over a dozen times.
* There's thousands of blogs and articles, each 1000s of words long and each recommending different things. I have yet to find a concrete guideline for what a 'sane default' set of choices are.
* Am I vulnerable to the issue described in the article? I guess I must be, given I don't see the server-side JWT validator doing anything special beyond validating the signature, so there's no validation of whether the token was generated for my app.[1][2]
* What are best practices for "client scopes"? I notice that the more I add the larger the JWT, but are there any gotchas to watch out for?
I think much of this boils down to there needing to be a published set of recommended defaults for common use cases, alongside some cleanup around deprecated/not-recommended config options.
[0] Given client secrets can be trivially extracted.
[1] Though I guess the fact I'm only using my own auth server and there's only one client means this isn't a problem.
[2] Isn't this how SSO works? One set of tokens to grant access to a bunch of different services?
- brabel 3y agoThis post is wrong in many ways. First, you know which app the access token was issued for, it's the "aud" in the JWT. Second, you should at least use the "state" parameter on authorization requests so that when you receive the access token via a redirect, you can guaranteee that the user was logging in intentionally and is now completing the flow (rather than coming from an attacker controlled website). Even better is to use PKCE! It should be common knowledge by now that you must use PKCE[1] if you really want to completely prevent CSRF attacks. OIDC helps with that because it practically makes this a requirement, but you don't need OIDC just for that. Finally, OIDC is not meant to increase OAuth security as this post tries to imply! It's just a layer on top of OAuth to establish an authentication procedure (OAuth intentionally leaves authentication out of scope as it's focused on authorization protocols). IT does end up improving certain things, but those things can be improved using simple OAuth extensions (like PKCE mentioned), only use OIDC if you actually need user information besides what's in the Access Token. [1] https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-protecting-redirect-based-f https://datatracker.ietf.org/doc/html/draft-ietf-oauth-secur...
- hsbauauvhabzb 3y agoI think this is a fairly elitist view and I disagree. I work in application security and still have trouble understanding all the behaviours of oauth and oidc, even after reading the specs multiple times. If I can’t understand it fully, how are you going to expect some developer who has no security or crypto background implement it correctly when nobody is there to validate the implementation? I feel like the oauth/oidc are insecure not because of the core logic, but because the design and terminology aren’t easily understood - that complexity IS a vulnerability.
- brabel 3y agoMy comment was pointing out mistakes in the claims from OP, I am not sure how you can interpret that as elitist. You may have read something into my comment that I did not say. For example, I didn't say OAuth is simple (though I am still to see a security framework that's better/simpler for the use cases OAuth sets out to solve).
- diarrhea 3y agoThis comment illustrates the issue on a meta level. The GP is a regular developer reaching out for help, raising issues experienced due the complexity of the matter. Very relatable. Along comes this comment's parent, essentially going "this is wrong in many ways, it's so easy if you just...". Very reminiscent of https://news.ycombinator.com/item?id=8863 https://news.ycombinator.com/item?id=8863 . Authentication and authorization need to be simple (enough) and, most importantly, offer a set of sane defaults. It mustn't require years worth of expertise. It is bound to be misused.
- dikei 3y ago> There's multiple overlapping standards, each with a dozen different variants. The Keycloak OIDC config refers to OAuth2 over a dozen times. To put it simply, OIDC = OAuth2 + id_token (a standard way for the provider to let your client knows who the user is) > There's thousands of blogs and articles, each 1000s of words long and each recommending different things. I have yet to find a concrete guideline for what a 'sane default' set of choices are. There's only one sane default for client-side application: Authorization Code with PKCE > Am I vulnerable to the issue described in the article? I guess I must be, given I don't see the server-side JWT validator doing anything special beyond validating the signature, so there's no validation of whether the token was generated for my app.[1][2] The id_token provide by OIDC has the standard field `aud`, which should contain you `client_id`. Match them together and you can check whether the tokens was issued for your app. > What are best practices for "client scopes"? I notice that the more I add the larger the JWT, but are there any gotchas to watch out for? Best practice for "client scopes" is as small as possible, the only required scope for OIDC is `openid`, which allows you to fetch the `id_token`. Any other scope like `email`, `profile`, etc... is optional, and provider-specific so should be look up from the provider documents.