Threat modeling OpenID Connect, OAuth 2.0 for beginners using OWASP Threat Dragon [Part 1]

You are reading this post because you probably came across Oauth and OpenID Connect at some point in time and tried to make sense out of it and couldn’t. Don’t worry we have all been there. I am not an expert in Oauth or OpenID Connect either so feel free to correct me. I tried to explain the concepts in simple plain English so you don’t require prior knowledge of the protocol to follow the post. After reading the post I hope some of the concepts will be a little bit clearer to you.

The best way to learn a new technology is by implementing it and also the difficult way. Hence in this blog, we will try to implement a “Hello World” OpenID Connect implementation and by doing so we will know how it works under the hood. 
It’s important to know how the technology works first before we try to find security issues causing relating to the technology. Hence first part of the post we will go through the OpenID and OAuth concepts and set up demo environment. In the second part of the post will go through the threat model. 
If you are already familiar with OAuth and OpenID Connect you can jump to the second part of the post here.

I will highly recommend checking out the video from Nate Barbettini here. Nate did an excellent job explaining OAuth and OpenID connect.

Let’s start by refreshing our memory with few basic definitions:
Authentication: The verification process which confirms a user’s identity. For example: logging with a username, password and/or multi-factor authentication to a web application.

Authorization: After authentication, systems need a way to determine what action/permissions do that user has on the system. For example, on Gmail you only have access to your own emails and not other user’s private emails.

How do authentication and authorization relates in OpenID world?

OAuth was initially designed for authorization not for authentication. But the industry added extra modules to make the protocol fit for authentication use case. In order to fit in the authentication use case, OpenID connect was introduced. The OpenID Connect stack looks like below:

OpenID Connect is used for Authentication.

OAuth 2.0 is used for Authorization.

But how do OpenID connect works under the hood?
To answer this question, we will walk through the flow diagram below. Do note the below example is based on the most common Oauth2.0 implementation which is authorization code grant flow. Before we go through the flow we will start by explaining the different components in the OAuth realm.

Resource owner: End user.
Client: The application which wants to use Google authentication (In this post to simulate that application we will use Google’s OAuth playground tool) 
Authorization server: Server which authenticates the client and provides the necessary details (tokens) to access resources from the resource servers (In this post we will use Google Authorization server).
Resource server: Data that the client application wants for example your application might want to obtain data from google services such as google contacts, gmail, etc. (In this post we will get Google contacts as resources).

OpenID Connect Data flow diagram- authorization code grant flow

I will quickly go through the above steps.

  1. End user wants to login to your application via “Login with Google” and send the request to your application. In this case, we will be using the demo tool (Google Oauth playground to simulate the application).
  2. Client application redirects the user to Google login page.
  3. This is where the user is presented with Login page or if already logged in then ask for consent.
  4. User grants their consent or reject.
  5. If the user grants access then the authorization server will send an authorization code to the client.
  6. With the authorization code, the Client requests for an access token and ID token. ID token is a unique identifier of the end user.
  7. With the access token, the application asks the resource server to ask for specific resources such as user’s contact details from Google contacts, etc.

In order to do this exercise, you will need an actual application which you will be able to do the authentication using Authorization/OpenID Connect server. I will be using Google OAuth 2.0 playground which will act as a client application and google authorization server which will act as OpenID Connect server.

For Google OpenID Connect documentation visit here.

For more details on the Google authentication playground tool, refer to this link.

Let’s re-run the flow with pictures and example this time.

Client application: https://developers.google.com/oauthplayground/ 
Resource server: Google Oauth2 API v2 https://www.googleapis.com/auth/userinfo.profile
Authorization server: https://accounts.google.com

  1. End user wants to login to your application via “Login with Google” and send the request to your application.
  2. Client application redirects the user to Google login page and provides the destination address.
Sign-in screen

https://accounts.google.com/signin/oauth/oauthchooseaccount?
client_id=407408718192.apps.googleusercontent.com&
as=y4cvua9GLoXDZRMfzqAo7g&
destination=https%3A%2F%2Fdevelopers.google.com&
approval_state=!ChRuamFVVmJpNm1ydzM2Y0NOOG5NcBIfQTJrNkZFeGRidHNaNEJxcmlYbTVkb215S3o0MWNCWQ%E2%88%99APNbktkAAAAAW-mYIPwMbaszUKnFzizoAbxI29K704oX
&xsrfsig=AHgIfE_RYGCrlq_V5983IW62XLCA8Vn0xw&
flowName=GeneralOAuthFlow
&hl=en-GB

Note the destination url.

3. This is where the user is presented with Login page or if already logged in then ask for consent.
4. User grants their consent or reject.

Consent screen

5. If the user grants access then the authorization server will send an authorization code to the client. You can see a 302 HTTP redirect with the URL specified.

Get Access token from the authorization server

6. With the authorization code, the Client requests for an access token and ID token. ID token is a unique identifier of the end user which is a JWT Token.

Request access token

Request / Response

POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-length: 277
content-type: application/x-www-form-urlencoded
user-agent: google-oauth-playground
code=4%2.....................-aQB4o-XsZo&redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&client_id=407408718192.apps.googleusercontent.com&client_secret=************&scope=&grant_type=authorization_code
...........
...........
Content-type: application/json; charset=utf-8
{
  "access_token": "ya29.XXXXXXXXXXXXXXXXXXXXXXXX", 
  "id_token": "XXXXXXXXXXXXXX…………………………… ", 
  "expires_in": 3600, 
  "token_type": "Bearer", 
  "scope": "https://www.googleapis.com/auth/contacts https://www.googleapis.com/auth/userinfo.profile", 
  "refresh_token": "1/XXXXXXXXYYYYYYYYYZZZZZZZZZZZU4Oj6JScUefOLYfR6VM"
}

If you want to look inside the id_token (JWT) token, you can using google apis as shown below. Include your id_token you received from above on the URL as follows.

https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XXXXXXXXXXXXXX..................

Decode your JWT Token

7. With the access token, the application asks the resource server to ask for specific resources such as End user’s contact details from Google contacts, etc.

Google contacts resource server showing the list of available methods

Request specific contact resource (note your contact will be different than the example below):
GET /m8/feeds/contacts/default/full/69d68ad0c744be5 HTTP/1.1
Host:
www.google.com
Authorization: Bearer ya29.XXXXXXXXXXX_YYYYYYYY0pThPa9b5Q-PIhnw3g2_ZZZZZZZZZZZZgAuS…………………………..

Note you have to include the access_token in your requests inside the Authorization header for the resource server to verify if you are authorized to view the resource.

Response from the resource server:

The above configuration for the Oauth flow is as follows:

Hopefully, the post is helpful. Feel free leave your comments below. Watch out for the second part of the post where we will go through the threat model using OWASP threat dragon and the mitigation.