-
-
Notifications
You must be signed in to change notification settings - Fork 666
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
proposal/discussion: OAuth - (for 1st party usage) only used (by the client) communication options must be allowed by authorization server #1964
Comments
I was thinking more about it - I think it is another topic compared which I opened, so probably we have 2 different vectors to cover.
ping @TobiasAhnoff - please confirm my understanding |
Based on the typical OAuth registration and "user" workflow, I would add one more level here.
So I'd suggest two requirements around scopes since there are granted at very different parts of the OAuth lifecycle.
|
I'm not sure we are talking about the same thing here (user registration vs configured client), I modified initial issue to be more clear and added:
For the 1st party solution (if there is no "discovery" in place), when an application uses the SSO service from the same organization, there should be no client registration available for being a OAuth Client. It is actually worth a separate requirement. |
A suggestion is to add something like this: L1,L2,L3: Verify that allowed scopes for each client asserts least privilege (especially if RS authorization is based on just a valid token and scopes, not using any additional token claims like identity of the caller or group membership) L2,L3: Verify that all clients are configured to only allow the required flow. For system integrations only allow grant type 'client-credentials' and for user interaction applications only allow grant type 'code' (Implicit and ROPC should not be supported, other additional flows like Device Authorization Grant might be supported if needed). Avoid reusing clients for different purposes (allowing e g both code and client-credentials). L1,L2,L3: Verify that grant type 'code' is always used together with PKCE L3: "Verify that all clients are confidential" (L1-L2 could allow for public clients) L3: "Verify that all clients are configured to use strong client authentication, mTLS or private-key-jwt" (L1-L2 could also use client-secret, note that verification 9.3.3 mandates mTLS, but private-key-jwt is also regarded sufficient by e g FAPI) L3: Verify that PAR with client authentication is used (for L1-L2 PAR is optional and could be used without client authentication) L3: Verify that sender-constrained access-tokens are used either using mTLS or DPoP (note that for L1 and L2 this does not require client authentication if used by public clients) L3: Verify that refresh-tokens are sender-constrained (by requiring client authentication for all token requests, while L1-L2 could allow one-time mitigation strategy for public clients, this is especially important if offline_access is granted, allowing long lived tokens not attached to active user sessions) |
Scope and response_type concerns are or will be covered by other requirements. Here there is need to build a requirement to say, that only allowed response_mode can be accepted by the authorization server (for the authorization request). |
Using the style from 51.2.5 it should sounds like:
|
I agree that 'response_mode' could be restricted, but is it possible (per client)? In my experience this not supported by some common OAuth/OIDC services, but I might be wrong...can´t find good reference documentation on this? |
When I was discussing the topic with "OAuth 2.0 for Browser-Based Applications" they thought it was a more general issue than browser-based apps and should belong to more general spec. Also, it should be solved when JAR/PAR is used for backend (confidential?) OAuth clients. In case it is not suitable for 3rd party solutions and for discovery mode, then we should limit the requirement for 1st party usage. Although OAuth is not even meant to be used like that. ping @randomstuff |
I'm not sure the security benefit is that great. I don't believe an attacker would gain a significant advantage in changing the
|
If redirect_uri is not matched with string-match and is (as an example) validated on origin level, it is enough to have one open-redirect, xss, referrer-leakage (for example you can set HTML attribute to an image, to have the effect) etc on the site, to steal the authorization code. If redirect_uri is validated correctly using string-match, but if you can change response_mode, then the client does not read the authorization code from the response and leaves it to be read to an attacker - there are still XSS or referrer-leakage vectors to read it, or it may leak from URL to logs and so on. I have proved stealing the authorization code many times during pentests and often I can say, that it could be not possible or it is more complicated if I (as an attacker) can not use other response_mode value than it is used by default. |
The suggested verification works, even if I think it is hard to do this with some AS services, but maybe it should be noted that there are other mitigations, perhaps?
|
I think a confidential client is not that helpful here, as the response_mode value must be limited for the authorization request, but the confidential client comes into play with the token request. I don't know enough about PAR to comment on that. |
Maybe AS providers should implement some features, not we need to change requirement to be more flexible? :) Although I agree that the risk-level is different when confidential client or/or client authentication is used, but it's the same with basically everything (public client vs confidential client). I think serving the idea and principle is enough at the moment:
|
Yes, I agree that PAR could be used to prevent tampering with this parameter (as well as other parameters) (as long as client authentication is required for the PAR endpoint i.e. for confidential clients). |
The problem is likely used if the OAuth client is public, but PAR comes into the play from level 3. It is suitable as "or" condition. |
For code flow it is (implicit should not be used), since the code can only be used by the confidential client who has the client-secret (which is a mitigation for the risk of the code leaking in a query-string or post-body).
I agree, is this good or should we remove/add anything?
|
As I said, it comes into play with the token request, but we need to defend also the authorization request. If an attacker was able to get the authorization code, then in case there is CSRF on the client side (51.3.5) and PKCE is not used, you can force the client to make the request, without having direct access to the token endpoint. |
I am not sure I understand...are you suggesting that the requirement should be just (this applies to all kinds of clients and flows)
or should we mention PAR (since it "defends the authorization request") and have
And remove the confidential client part since this is not relevant? Or is this only an issue for public clients so it could be like this?
|
Goes in via #2140
|
I added the "keep it simple" version. If it requires some further improvement, please let me know. Otherwise we are done here. |
I think it is a good thing to have. But, in my experience it is often not possible to do this (since authorization servers in general does not support configuration of allowed response_modes per client), so my concern is that we might add a requirement for all levels that not many implementations can do...is that ok or should requirements in ASVS for L1 and L2 be required to also have "good" implementation support? If this is ok, then I think 51.2.12 is good. |
I watched it from my pen-test experience and I can say, if the requirement is satisfied, it gives enough security benefits to be a worthy requirement. So half of your concern can be fixed with a feature request to Keycloak? :) |
Two things kind-of bothers me here:
What is possible with dynamic client registration is that the client can use So could this be reworded as something such as (which focused on the goal):
This could be achieved:
|
@elarlang I agree that it is a worthy requirement and I like rewording with focus on the goal as @randomstuff suggested, perhaps add how this can be achieved to the requirement
|
Personally, I don't care how it is achieved. One may also put a WAF rule and block all other requests that are not with response_mode=expected. I'll update the requirement with next area51 PR. |
Via #2157
|
Done with this update. |
UPDATE: The focus for the issue is set to only handle the response_mode parameter validation, jump to #1964 (comment)
spin-off from #1916 "Discussion/Proposal 2"
For a situation, where OAuth is used as a "first-party" authorization solution and the application needs one and only way how it communicates with the authorization server, then for the OAuth client must be configured and the Authorization Server must validate, that: only the expected values are allowed, that is implemented by the client:
offline_access
may be worth special mentionedit: scope in mind - authorization request from OAuth Client to OAuth Authorization Server
--
Feedback from @tghosth in #1916 (comment)
--
Overlap by recommendation from @TobiasAhnoff in #1925
Although response_type and response_mode are not directly privilege, those are all related with allowed flow.
The text was updated successfully, but these errors were encountered: