I've spent the last few hours reading about the Oauth2 protocol. From my understanding, the main motivation for this protocol is that the resource owner does not have to share their credentials with 3rd party (client) applications, only the resource server.
In this post, I have used the roles as defined in the Oauth2 RFC. However, I have not distinguished between the resource server and authorization server. I assume for the simplicity that they are the same and refer to them as "resource server".
I can see two different chain of events. Assume that both scenarios start with a resource owner with the intent to let a client access a protected resource.
Case 1, GUI provided by the resource server
Client forwards resource owner to the resource server's login page.
Resource owner provides his/her credentials at the resource server's GUI.
On success, the resource server forwards the resource owner to the Client and provides the user client with a token.
Case 2, GUI provided by the Client
The client asks the resource owner to provide his/her credentials to its own GUI.
The client sends the provided credentials to the resource server.
On success, the client obtains a token and access to the resource server.
My concern is case 2. How hard would it be for the client to obtain full privileges on the resource server if it, instead of authenticating as a client, authenticates as the resource owner? The RFC states the following as a reason to use OAuth2 instead of letting the client handle the resource owners credentials:
"Third-party applications gain overly broad access to the resource
owner's protected resources, leaving resource owners without any
ability to restrict duration or access to a limited subset of
resources."
The RFC further states:
"Third-party applications are required to store the resource
owner's credentials for future use, typically a password in
clear-text."
This could very well be saved by the client in case 2.
So... Can you assume that a client that implements Oauth2 (In case 2) is more secure than one that does not? Is it possible for a resource server to implement mechanisms to prevent such things as these?
You can assume that using a proper OAuth2 implementation your system is more secure than a conventional user/pass based system.
Case 1 is clearly superior since no user credentials are exposed to the client.
Case 2 is only a possibility, many OAuth2 providers don't support it at all. Even the standard discourages using it, it seems to be there only as a fallback when the plain old user/pass based logic still must be used for some strange reason. This case is still slightly better as the client application has the possibility not to store your credentials at all. The specified credentials can be dropped right after creating the OAuth request and only the granted tokens should be stored. Gaining a refresh token, there is no need to ask for your user/pass again.
Note that stealing the tokens from the application is still a security risk, but the thief won't have full privilege with your credentials, will only have the access rights you have granted to the application. Furthermore, access tokens expire and the provider should support revoking refresh tokens.
Consider case2:
Lets say the resource owner has provided his/her credentials to the client and as you stated the client has to store the password somewhere in plain text form.
1) But can we trust the client that it would not access any information without your permission ??
2) what if someone hacks the client database and gain access to all the credentials which may contain sensitive information like netbanking passwords etc..,??
so to prevent these security-issues, the resource owner deals directly with resource server and sets the permissions for the client to access only information which it wants and not a bit more. Then the server issues a token(like a gatepass) to the client and whenever the client needs some information it has to send the token.
so its best not to give the client our credentials for security reasons.
Related
I'm currently working on oauth2 implementation and i wonder about CSRF attack.
I so very good explanation : in this scheme https://image.slidesharecdn.com/owasp-nulloauth2-160803124628/95/oauth-20-security-considerations-11-638.jpg?cb=1470228518 or this video https://www.youtube.com/watch?v=_xrhWLqX1j0 but i dont understand the goal.
At the end my account will have access to the attacker account, i cant get data from it but not the reverse. Am I right ? What is the benefit for the attacker to do this ?
Thank's for your answer,
There are several other answers (ex:- this and this) explaining the background of state and how it avoid csrf.
Best thing is to refer what is given by specification creators. RFC6810 - OAuth 2.0 Threat Model and Security Considerations contains many threats and counter measurements for OAuth 2.0. In that Threat: CSRF Attack against redirect-uri gives a solid overview on the threat. Following is an extract,
An attacker could authorize an authorization "code" to
their own protected resources on an authorization server. He then
aborts the redirect flow back to the client on his device and tricks
the victim into executing the redirect back to the client. The
client receives the redirect, fetches the token(s) from the
authorization server, and associates the victim's client session with
the resources accessible using the token.
Now client has tokens which belongs to attacker. No, attacker won't be able to access anything that belongs to client in resource server. But if client perform a storing operation (ex :- Document create), this will be sent to malicious party. Now malicious party get access rights to those freshly created resource. This is highlighted as below,
The
effective impact depends on the type of resource accessed. For
example, the user may upload private items to an attacker's
resources. Or, when using OAuth in 3rd-party login scenarios, the
user may associate his client account with the attacker's identity at
the external Identity Provider. In this way, the attacker could
easily access the victim's data at the client by logging in from
another device with his credentials at the external Identity
Provider.
So basically threat is associated with fresh data created at resource server.
I'm trying to implement authentication/authorization in my solution. I have a bunch of backend services(including identity service) under API Gateway, "backend for frontend" service, and SPA (React + Redux). I have read about OAuth2.0/OpenIdConnect, and I can't understand, why I shouldn't use Resource owner password flow?
A client ( my backend for frontend server ) is absolutely trusted, I can simply send users login/password to the server, then it forwards them to Identity server, receives the access token && refresh token and stores refresh token in memory(session, Redis, etc), and send the access token to SPA, which stores it in local storage. If SPA will send a request with the expired access token, the server will request a new one using refresh token and forwards the request to API Gateway with the new access token.
I think in my case a flows with redirects can provide worth user experience, and are too complicated.
What have I misunderstood? What potholes I'll hit if I'll implement authentication/authorization as I described above?
OAuth 2.0 specification's introduction section gives one key information on the problem it tries to solve. I have highlighted a section below,
In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner's
credentials. In order to provide third-party applications access to
restricted resources, the resource owner shares its credentials with
the third party
As a summary what OAuth wants to provide is an authorization layer which removes the requirement of exposing end user credentials to a third party. To achieve this it presents several flows (ex:- Authorization code flow, Implicit flow etc.) to obtain tokens which are good enough to access protected resources.
But not all clients may able to adopt those flows. And this is the reason OAuth spec introduce ROPF. This is highlighted from following extraction,
The resource owner password credentials grant type is suitable in
cases where the resource owner has a trust relationship with the
client, such as the device operating system or a highly privileged
application.The authorization server should take special care when
enabling this grant type and only allow it when other flows are not
viable.
According to your explanation, you have a trust relationship with client. And your flow seems to be work fine. But from my end I see following issues.
Trust
The trust is between end user and the client application. When you release and use this as a product, will your end users trust your client and share their credentials.? For example, if your identity server is Azure AD, will end users share Azure credentials with your client.?
Trust may be not an issue if you are using a single identity server and it will be the only one you will ever use. Which brings us the next problem,
Support for multiple identity servers
One advantage you get with OAuth 2 and OpenID Connect is the ability to use multiple identity servers. For example, you may move between Azure AD, Identityserver or other identity servers which of customer's choice (ex:- they already use on internally and they want your app to use it). Now if your application wants to consume such identity servers, end users will have to share credentials with your client. Sometimes, these identity servers may not even support ROPF flow. And yet again TRUST become an issue.!
A solution ?
Well I see one good flow you can use. You have one front end server and a back-end server. I believe your client is the combination of both. If that's the case you could try to adopt authorization code flow. It's true your front end is a SPA. But you have a backend you can utilise to obtain tokens. Only challenge is to connect front end SPA with back end for token response (pass access token to SPA and store other tokens in back-end). With that approach, you avoid above mentioned issues.
I understand the OAuth 2.0 spec. allows third-party applications to grant limited access to the application, either on behalf of a resource owner or by allowing the third-party application to obtain access on its own behalf.
I have a scenario, where I have an application and I need the user to get authenticated with some IAM provider. The roles and privileges are configured in the authorization server for each user. I can query the introspection point of the authorization server and based on the scope details, my application can decide the access to any resource for the user.
In this case, the user is not the resource owner. The types of resources the user can access is decided by my application, instead of the user allowing/denying the application to access resources.
Since the user is not the resource owner, can OAuth/OpenId Connect be used in this scenario ? Is it possible with WSO2 IAM?
I tried the playground sample which is available in WSO2. Once the user logs in, there is a window which asks "playground requests access to your profile information" and requesting the user to allow/deny. Can this be avoided, since in my case the user is not allowed to make any decisions ?
If not, what are the other options to authorize/limit access to resources which is decided by the authorization server/resource server, instead of user granting access ?
Thanks,
Albie Morken
In this case, the user is not the resource owner. The types of resources the user can access is decided by my application, instead of the user allowing/denying the application to access resources.
In your scenario, you are relying on tokens issued by authorisation server to access a protected resource. The protected resource is your application. And this application must have internal mechanisms to verify the tokens it receives to grant access.
Short answer to your question is - YES
You can use openID connect for this scenario. And you have two options to adopt,
1. Use access tokens with introspection end point
You can use access tokens to grant access to your application. The client should send the access token as a bearer token as described in RFC6750. When the application end point receives a request, this access token can be validated against introspection endpoint RFC7662
2. Use ID token
ID tokens too can be used as bearer tokens.ID token is a JWT (RFC7519) and is self contained. It contains validation mechanisms as described by OpenID connect spec which are self sufficient to allow grant. And also to you can check claims it contains to authorise the end user. More can be found from this link.
I tried the playground sample which is available in WSO2. Once the user logs in, there is a window which asks "playground requests access to your profile information" and requesting the user to allow/deny. Can this be avoided, since in my case the user is not allowed to make any decisions ?
Consent page can be disabled. According to spec. it can be done by configuring identity.xml as follow,
<SkipUserConsent>true</SkipUserConsent>
It is described in their documentation too.
Hope this helped.
p.s - WSO2IS contains inbuilt XACML engine. XACML is the standard for access control. You can fine more information from this link.
According to the IETF's OAuth 2.0 document RFC 6749, it is implied that it is a good practice not to expose the token issued by the authorization server to the resource owner:
The authorization code provides a few important security benefits,
such as the ability to authenticate the client, as well as the
transmission of the access token directly to the client without
passing it through the resource owner's user-agent and potentially
exposing it to others, including the resource owner.
Do you know any reason for this?
It highlights that access tokens are credentials that must be kept confidential and available only to:
the authorization server that issued them
the resource server for which the credentials are valid
the client application application to which they were issued
Not even the resource owner needs access to these credentials; the most important part of the authorization code is of course reducing the risk of exposure to others, however, having an explicit note to mention the resource owner makes it clear that the target recipient of an access token is the client application.
Why would anyone use OAuth 2 with this kind of grant? I mean, if the client already has the name and password of the Resource Owner, why not just authenticate as the Resource Owner using whatever authentication vehicle is used by the Resource Server?
I do not understand the rationale here. Can someone explain it?
As the spec mentions, the Resource Owner Password Credentials grant is for migration purposes and applicable only in scenario's where (typically) the Client and the Authorization Server are controlled by the same party, https://www.rfc-editor.org/rfc/rfc6749#section-1.3.3:
The resource owner password credentials (i.e., username and password)
can be used directly as an authorization grant to obtain an access
token. The credentials should only be used when there is a high
degree of trust between the resource owner and the client (e.g., the
client is part of the device operating system or a highly privileged
application), and when other authorization grant types are not
available (such as an authorization code).
It allows for utilizing a standard token and protocol on the leg between Client and Resource server (e.g. OAuth 2.0 Bearer Token), whilst using a "to-be-deprecated" way of getting a token between Client and Authorization Server. https://www.rfc-editor.org/rfc/rfc6749#section-10.7:
The resource owner password credentials grant type is often used for
legacy or migration reasons. It reduces the overall risk of storing
usernames and passwords by the client but does not eliminate the need
to expose highly privileged credentials to the client.
This grant type carries a higher risk than other grant types
because it maintains the password anti-pattern this protocol seeks
to avoid. The client could abuse the password, or the password
could unintentionally be disclosed to an attacker (e.g., via log
files or other records kept by the client).
Additionally, because the resource owner does not have control over
the authorization process (the resource owner's involvement ends when
it hands over its credentials to the client), the client can obtain
access tokens with a broader scope than desired by the resource
owner. The authorization server should consider the scope and
lifetime of access tokens issued via this grant type.
The authorization server and client SHOULD minimize use of this
grant type and utilize other grant types whenever possible.
I will provide another point of view.
OAuth 2.0 is a great protocol for common web applications. Some applications, however, use much stronger authentication / authorization mechanism. For these cases, it makes sense to allow token establishment using a strong method. An example of such application can be a banking API - it can use classic OAuth 2.0 flow on web (using bank's website) and strong data signatures using protocols like PowerAuth 2.0 (I am an author of this solution) for native mobile or desktop apps.