Dynamic Analysis of Android Apps
Ralph Meier
Find the appropriate OAuth flow for different application types
In the following, OAuth always refers to OAuth 2.0, unless another version is explicitly referenced. The basic idea behind OAuth is to allow authorised access to third-party applications without having to have a copy of the users’ access data and to authenticate the users themselves. OAuth also allows you to control what the third-party application is allowed to see and for how long. In addition, access can be revoked for each application.
The OAuth 2.0 specification provides various OAuth processes, so-called flows. By specifying grant_type when initiating, the flow is defined and executed according to its scheme.
An overview of the actors involved in different OAuth flows:
Actor | Description |
---|---|
Client / Client Application | A web application or other application that wants access to protected resources with the help and on behalf of the resource owner. |
Resource Owner | The user who grants access to the protected resource. If the resource owner is a user, this is also referred to as the end user. |
Resource Server | Server that manages the protected resources. |
Authorization Server | Server that authenticates the resource owner and issues access tokens for access to the desired resource with the resource owner’s consent. |
Term | Description |
---|---|
Authorization Grant | Reflects the access data of the resource owner. This is used to request the Access Token from the Authorization Server. |
Access Token | Access tokens to access protected resources. They represent an authorization for the respective client. The information they contain includes exact scope and defined access duration. |
Refresh Token | These are optionally issued with an Access Token. With a Refresh Token, a new Access Token can be collected from the Authorization Server after the validity of the Access Token has expired. |
The following abstract flow serves as a general understanding of the OAuth process, the various flows differ from it.
grant_type="authorization_code"
Here, an authorization server is located between the client and the resource owner. Instead of a direct request from the client to the resource owner, the resource owner is directed via a browser (user agent) to an authorization server. There, the resource owner authenticates himself to the authorization server and assigns the authorization to the client. The resource owner is then forwarded back to the client with an authorization code. The client can then collect the access token with the authorization code. With the access token request, the client still has to authenticate itself if it is a confidential client or if it has client access data.
Issuing a refresh token together with the access token is optional.
The authorization code issued should be valid for a maximum of 10 minutes. It should be cancelled shortly after use to prevent the risk of an authorization code leak. The authorization code must not be used more than once, if this happens the request should be discarded and all issued tokens based on this authorization code should be cancelled.
In the event of an error, the resource owner should be informed of the circumstances by the authorization server.
The added security value comes from the fact that the access token is sent directly from the authorization server to the client and does not go through the resource owner’s browser and is thus disclosed to him and possible other third parties.
response_type="token"
Step 6 is the execution of the received script from step 5 to read the access token from the URI fragment.
This process is a simplified version of the Authorisation Code flow and is designed for public client types. In this flow, an access token is issued directly to the client and an authorization code is therefore not required.
The authentication of the client by the authorization server is omitted, as public client types cannot implement the secure storage of their own client access data.
With this transfer, the access token becomes visible to the resource owner and other applications that have access to the resource owner’s browser.
The implicit flow speeds up the OAuth process by omitting the receipt of the authorization code and its exchange to obtain the access token. However, this makes the access token accessible to other parties and reduces its security.
The Implicit Flow does not support refresh tokens.
grant_type="password"
Here, the username and password of the resource owner are used directly as an authorization grant to obtain an access token.
This flow should only be used if the client does not currently support any other OAuth flow and OAuth must be used. The use of this flow is not recommended according to Internet-Draft, as the resource owner’s credentials are leaked to the client, many thanks to @alcastronic for this advice.
If a long-lived access or refresh token is issued to the client, the retransmission of the access data can be waived for this period of time. In this way, the resource owner enters his access data once and the client saves the token received. This makes sense in isolated areas of application. This can also replace existing direct authentication procedures such as HTTP Basic Authentication.
After issuing the access token, the client must remove the received access data of the resource owner from its memory.
Since the access token request here primarily consists of a user name and password, or rather this constitutes the authorization grant, the associated endpoint of the authorization server must be protected against brute force attacks.
grant_type="client_credentials"
This flow is used when the client is the resource owner itself or the client has been previously authorised for the requested resource. Machine-To-Machine (M2M) applications in particular often use this flow, such as daemons or services in the backend. The client only uses its credentials or other forms of client authentication towards the authorization server. This flow should only be used with trusted clients.
The issuing of refresh tokens is optional, but makes sense depending on the application and the flow used. If the validity of the access token has expired, the client can use it to have a new access token issued by the authorization server if it is in possession of a refresh token. The refresh token is typically long-lived and bound to the client that made the initial access token request. If it is a confidential client or if it authenticated itself with client credentials in the initial request, it must provide them again. In addition to the client access data, the authorization server must also check, if necessary, whether the client comes with the refresh token intended for it.
If all supplied access data and the refresh token are valid, a new access token and optionally a new refresh token are issued. When a new refresh token is issued, the client must replace the old one with the new refresh token. The authorization server, on the other hand, can cancel the old refresh token, but does not have to. The scope of the new refresh token corresponds to the scope of the old refresh token.
When implementing a new OAuth solution, it is important to select the appropriate flow based on the specified client, applicable security requirements and security considerations. In the case of a classic web application with a backend on a web server, which can securely store client access data and protect it from unauthorised access, the authorization code flow is the appropriate choice. Whether optional refresh tokens are issued must be analysed depending on the application scenario.
Currently, OAuth 2.1 is in the making, which is to unify the additionally published RFCs to the OAuth 2.0 core RFC 6749.
We are going to monitor the digital underground for you!
Ralph Meier
Ralph Meier
Ralph Meier
Ralph Meier
Our experts will get in contact with you!