Attacking Authentication Mechanisms  

Introduction to OAuth


OAuth is a standard that enables secure authorization between services. As such, OAuth is commonly used in Single Sign-On (SSO) scenarios, enabling users to log in to a single service to access multiple different services. OAuth achieves this without sharing the user's credentials between services.

Before diving into attacks and misconfigurations that can lead to security flaws in OAuth, let us first discuss how OAuth works.


OAuth Entities

The OAuth protocol comprises the following acting entities:

  • The Resource Owner: The entity that owns the resource. This is typically the user
  • The Client: The service requesting access to the resource on behalf of the resource owner
  • The Authorization Server: The server that authenticates the resource owner and issues access tokens to the client
  • The Resource Server: The server hosting the resources the client requests to access

Note that it is not required that these entities are physically separate. For instance, the authorization and resource servers may be the same system.

On an abstract level, the communication flow between these entities works as follows:

  1. The client requests authorization from the resource owner
  2. The client receives an authorization grant from the resource owner
  3. The client presents the authorization grant to the authorization server
  4. The client receives an access token from the authorization server
  5. The client presents the access token to the resource server
  6. The client receives the resource from the resource server

image

Now, let us take a look at a more concrete example to make it more clear. We will consider the following entities:

  • Resource owner: The user, who we will name John
  • Client: An imaginary cybersecurity training platform called academy.htb
  • Authorization Server: An imaginary platform for version control called hubgit.htb
  • Resource Server: For simplicity's sake, this is the same as the authorization server: hubgit.htb

Let us assume that John wants to login to academy.htb using his hubgit.htb account. Then, the communication flow may look like this:

  1. John clicks Login with hubgit.htb on academy.htb. He is redirected to the login page of hubgit.htb
  2. John logs in to hubgit.htb and consents to giving access to his profile to the third-party service academy.htb. Afterward, hubgit.htb issues an authorization grant to academy.htb
  3. academy.htb presents the authorization grant to hubgit.htb
  4. hubgit.htb validates the authorization grant and issues an access token that enables academy.htb to access John's profile
  5. academy.htb presents the access token to hubgit.htb in a request to an API endpoint that accesses John's profile information
  6. hubgit.htb validates the access token and provides academy.htb with John's profile information

image

After the exchange, academy.htb can access John's profile information on hubgit.htb, i.e., make requests to hubgit.htb in John's name. This is achieved without sharing John's credentials with academy.htb.

OAuth defines different grants used for different contexts and use cases. We will only look at the two most common grant types, the authorization code grant and the implicit grant. For more details on the less common grant types, look at the OAuth standard. Remember that not all requests are initiated from the user's browser. Some requests happen directly between the client and resource server and are thus transparent to the user.


Authorization Code Grant

The authorization code grant is the most common and secure OAuth grant type. This grant type's flow is the same as the abstract flow discussed above.

image

Step 1: Authorization Request

This grant type starts with the authorization request from the client academy.htb to the authorization server hubgit.htb:

GET /auth?client_id=1337&redirect_uri=http://academy.htb/callback&response_type=code&scope=user&state=a45c12e87d4522 HTTP/1.1 
Host: hubgit.htb

This request contains multiple interesting GET parameters:

  • client_id: A unique identifier for the client academy.htb
  • redirect_uri: The URL to which the browser will be redirected after a successful authorization by the resource owner
  • response_type: This is always set to code for the authorization code grant
  • scope: This indicates what resources the client academy.htb needs to access. This parameter is optional
  • state: A random nonce generated by the client that serves a similar purpose to a CSRF token tying the authorization request to the following callback request. This parameter is optional

Step 2: Resource Owner Authentication

The authorization server hubgit.htb will request the user to log in and authorize the client academy.htb to access the requested resources.

Step 3: Authorization Code Grant

The authorization server redirects the browser to the URL specified in the redirect_uri parameter of the authorization request:

GET /callback?code=ptsmyq2zxyvv23bl&state=a45c12e87d4522 HTTP/1.1
Host: academy.htb

This request contains two parameters:

  • code: The authorization code issued by the authorization server
  • state: The state value from the authorization request to tie these two requests together

Step 4: Access Token Request

After obtaining the authorization code, the client requests an access token from the authorization server:

POST /token HTTP/1.1
Host: hubgit.htb

client_id=1337&client_secret=SECRET&redirect_uri=http://academy.htb/callback&grant_type=authorization_code&code=ptsmyq2zxyvv23bl

In addition to the previously discussed parameters, this request contains two new parameters:

  • client_secret: A secret value assigned to the client by the authorization server during the initial registration. This value authenticates the client to the authorization server
  • grant_type: This is always set to authorization_code for the authorization code grant

Step 5: Access Token Grant

The authorization server validates the authorization code and issues a valid access token for the resource server in response to the token request:

{
  "access_token":"RsT5OjbzRn430zqMLgV3Ia",
  "expires_in":3600
}

Step 6: Resource Request

The client now holds a valid access token for the resource server and can use this access token to request the resource owner's information:

GET /user_info HTTP/1.1
Host: hubgit.htb
Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia

Step 7: Resource Response

The resource server validates the access token and responds with the resource owner's information:

{username: "john", email: "[email protected]", id: 1337}

Implicit Grant

The implicit code grant is shorter than the authorization code grant as the authorization code exchange is skipped. This results in a more straightforward implementation at the cost of lower security since access tokens are exposed in the browser.

Therefore, it is generally preferable to use the authorization code grant if possible. However, in some cases, the client might not be able to store the authorization code securely. This might be the case for some client-side JavaScript applications. The implicit grant was specifically designed for these use cases. It can be used when quick access is required, and the security risks associated with token exposure have been evaluated and deemed acceptable.

image

Step 1: Authorization Request

The implicit grant type starts with a slightly different authorization request compared to the authorization code grant type:

GET /auth?client_id=1337&redirect_uri=http://academy.htb/callback&response_type=token&scope=user&state=a45c12e87d4522 HTTP/1.1 
Host: hubgit.htb

The response_type parameter is set to token. All other parameters retain the same meaning.

Step 2: Resource Owner Authentication

The authorization server hubgit.htb will request the user to log in and authorize the client academy.htb to access the requested resources. This is the same as in the authorization code grant.

Step 3: Access Token Grant

This step is the main difference from the authorization token grant. Like before, the authorization server redirects the browser to the URL specified in the authorization request's redirect_uri parameter. However, instead of providing an authorization code, this redirect already contains the access token in a URL fragment where it can be extracted using suitable client-side JavaScript code:

GET /callback#access_token=RsT5OjbzRn430zqMLgV3Ia&token_type=Bearer&expires_in=3600&scope=user&state=a45c12e87d4522 HTTP/1.1
Host: academy.htb

Step 4: Resource Request

The client now holds a valid access token for the resource server and can use this access token to request the resource owner's information. This is the same as in the authorization code grant.

GET /user_info HTTP/1.1
Host: hubgit.htb
Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia

Step 5: Resource Response

The resource server validates the access token and responds with the resource owner's information. This is the same as in the authorization code grant.

{username: "john", email: "[email protected]", id: 1337}

Remarks

The description of OAuth given in this section applies to OAuth2.0, which is the latest version at the time of writing this module. However, there is a draft for an updated version OAuth2.1. One of the most notable differences to OAuth2.0 is the removal of the implicit grant, as described here.

Previous

+10 Streak pts

Next