OWASP Testing Guide
  • Foreword by Eoin Keary
  • Frontispiece
  • Introduction
  • The OWASP Testing Framework
    • The Web Security Testing Framework
    • Penetration Testing Methodologies
  • Web Application Security Testing
    • Introduction and Objectives
    • Information Gathering
      • Conduct Search Engine Discovery Reconnaissance for Information Leakage (WSTG-INFO-01)
      • Fingerprint Web Server (WSTG-INFO-02)
      • Review Webserver Metafiles for Information Leakage (WSTG-INFO-03)
      • Enumerate Applications on Webserver (WSTG-INFO-04)
      • Review Webpage Content for Information Leakage (WSTG-INFO-05)
      • Identify Application Entry Points (WSTG-INFO-06)
      • Map Execution Paths Through Application (WSTG-INFO-07)
      • Fingerprint Web Application Framework (WSTG-INFO-08)
      • Fingerprint Web Application (WSTG-INFO-09)
      • Map Application Architecture (WSTG-INFO-10)
    • Configuration and Deployment Management Testing
      • Test Network Infrastructure Configuration (WSTG-CONF-01)
      • Test Application Platform Configuration (WSTG-CONF-02)
      • Test File Extensions Handling for Sensitive Information (WSTG-CONF-03)
      • Review Old Backup and Unreferenced Files for Sensitive Information (WSTG-CONF-04)
      • Enumerate Infrastructure and Application Admin Interfaces (WSTG-CONF-05)
      • Test HTTP Methods (WSTG-CONF-06)
      • Test HTTP Strict Transport Security (WSTG-CONF-07)
      • Test RIA Cross Domain Policy (WSTG-CONF-08)
      • Test File Permission (WSTG-CONF-09)
      • Test for Subdomain Takeover (WSTG-CONF-10)
      • Test Cloud Storage (WSTG-CONF-11)
      • Testing for Content Security Policy (WSTG-CONF-12)
    • Identity Management Testing
      • Test Role Definitions (WSTG-IDNT-01)
      • Test User Registration Process (WSTG-IDNT-02)
      • Test Account Provisioning Process (WSTG-IDNT-03)
      • Testing for Account Enumeration and Guessable User Account (WSTG-IDNT-04)
      • Testing for Weak or Unenforced Username Policy (WSTG-IDNT-05)
    • Authentication Testing
      • Testing for Credentials Transported over an Encrypted Channel (WSTG-ATHN-01)
      • Testing for Default Credentials (WSTG-ATHN-02)
      • Testing for Weak Lock Out Mechanism (WSTG-ATHN-03)
      • Testing for Bypassing Authentication Schema (WSTG-ATHN-04)
      • Testing for Vulnerable Remember Password (WSTG-ATHN-05)
      • Testing for Browser Cache Weaknesses (WSTG-ATHN-06)
      • Testing for Weak Password Policy (WSTG-ATHN-07)
      • Testing for Weak Security Question Answer (WSTG-ATHN-08)
      • Testing for Weak Password Change or Reset Functionalities (WSTG-ATHN-09)
      • Testing for Weaker Authentication in Alternative Channel (WSTG-ATHN-10)
      • Testing Multi-Factor Authentication (MFA) (WSTG-AUTH-11)
    • Authorization Testing
      • Testing Directory Traversal File Include (WSTG-ATHZ-01)
      • Testing for Bypassing Authorization Schema (WSTG-ATHZ-02)
      • Testing for Privilege Escalation (WSTG-ATHZ-03)
      • Testing for Insecure Direct Object References (WSTG-ATHZ-04)
      • Testing for OAuth Authorization Server Weaknesses
      • Testing for OAuth Client Weaknesses
      • Testing for OAuth Weaknesses (WSTG-ATHZ-05)
    • Session Management Testing
      • Testing for Session Management Schema (WSTG-SESS-01)
      • Testing for Cookies Attributes (WSTG-SESS-02)
      • Testing for Session Fixation (WSTG-SESS-03)
      • Testing for Exposed Session Variables (WSTG-SESS-04)
      • Testing for Cross Site Request Forgery (WSTG-SESS-05)
      • Testing for Logout Functionality (WSTG-SESS-06)
      • Testing Session Timeout (WSTG-SESS-07)
      • Testing for Session Puzzling (WSTG-SESS-08)
      • Testing for Session Hijacking (WSTG-SESS-09)
      • Testing JSON Web Tokens (WSTG-SESS-10)
    • Input Validation Testing
      • Testing for Reflected Cross Site Scripting (WSTG-INPV-01)
      • Testing for Stored Cross Site Scripting (WSTG-INPV-02)
      • Testing for HTTP Verb Tampering (WSTG-INPV-03)
      • Testing for HTTP Parameter Pollution (WSTG-INPV-04)
      • Testing for Oracle
      • Testing for MySQL
      • Testing for SQL Server
      • Testing PostgreSQL
      • Testing for MS Access
      • Testing for NoSQL Injection
      • Testing for ORM Injection
      • Testing for Client-side
      • Testing for SQL Injection (WSTG-INPV-05)
      • Testing for LDAP Injection (WSTG-INPV-06)
      • Testing for XML Injection (WSTG-INPV-07)
      • Testing for SSI Injection (WSTG-INPV-08)
      • Testing for XPath Injection (WSTG-INPV-09)
      • Testing for IMAP SMTP Injection (WSTG-INPV-10)
      • Testing for File Inclusion
      • Testing for Code Injection (WSTG-INPV-11)
      • Testing for Command Injection (WSTG-INPV-12)
      • Testing for Buffer Overflow (WSTG-INPV-13)
      • Testing for Format String Injection (WSTG-INPV-13)
      • Testing for Incubated Vulnerability (WSTG-INPV-14)
      • Testing for HTTP Splitting Smuggling (WSTG-INPV-15)
      • Testing for HTTP Incoming Requests (WSTG-INPV-16)
      • Testing for Host Header Injection (WSTG-INPV-17)
      • Testing for Server-side Template Injection (WSTG-INPV-18)
      • Testing for Server-Side Request Forgery (WSTG-INPV-19)
      • Testing for Mass Assignment (WSTG-INPV-20)
    • Testing for Error Handling
      • Testing for Improper Error Handling (WSTG-ERRH-01)
      • Testing for Stack Traces (WSTG-ERRH-02)
    • Testing for Weak Cryptography
      • Testing for Weak Transport Layer Security (WSTG-CRYP-01)
      • Testing for Padding Oracle (WSTG-CRYP-02)
      • Testing for Sensitive Information Sent via Unencrypted Channels (WSTG-CRYP-03)
      • Testing for Weak Encryption (WSTG-CRYP-04)
    • Business Logic Testing
      • Introduction to Business Logic
      • Test Business Logic Data Validation (WSTG-BUSL-01)
      • Test Ability to Forge Requests (WSTG-BUSL-02)
      • Test Integrity Checks (WSTG-BUSL-03)
      • Test for Process Timing (WSTG-BUSL-04)
      • Test Number of Times a Function Can Be Used Limits (WSTG-BUSL-05)
      • Testing for the Circumvention of Work Flows (WSTG-BUSL-06)
      • Test Defenses Against Application Misuse (WSTG-BUSL-07)
      • Test Upload of Unexpected File Types (WSTG-BUSL-08)
      • Test Upload of Malicious Files (WSTG-BUSL-09)
      • Test Payment Functionality (WSTG-BUSL-10)
    • Client-Side Testing
      • Testing for Self DOM Based Cross-Site Scripting
      • Testing for DOM-Based Cross Site Scripting (WSTG-CLNT-01)
      • Testing for JavaScript Execution (WSTG-CLNT-02)
      • Testing for HTML Injection (WSTG-CLNT-03)
      • Testing for Client-side URL Redirect (WSTG-CLNT-04)
      • Testing for CSS Injection (WSTG-CLNT-05)
      • Testing for Client-side Resource Manipulation (WSTG-CLNT-06)
      • Testing Cross Origin Resource Sharing (WSTG-CLNT-07)
      • Testing for Cross Site Flashing (WSTG-CLNT-08)
      • Testing for Clickjacking (WSTG-CLNT-09)
      • Testing WebSockets (WSTG-CLNT-10)
      • Testing Web Messaging (WSTG-CLNT-11)
      • Testing Browser Storage (WSTG-CLNT-12)
      • Testing for Cross Site Script Inclusion (WSTG-CLNT-13)
      • Testing for Reverse Tabnabbing (WSTG-CLNT-14)
    • API Testing
      • Testing GraphQL (WSTG-APIT-01)
  • Reporting
    • Reporting
    • Vulnerability Naming Schemes
  • Appendix
    • Testing Tools Resource
    • Suggested Reading
    • Fuzz Vectors
    • Encoded Injection
    • History
    • Leveraging Dev Tools
  • Testing Checklist
  • Table of Contents
  • REST Assessment Cheat Sheet
  • API Testing
Powered by GitBook
On this page
  • Summary
  • Test Objectives
  • How to Test
  • Testing for Deprecated Grant Types
  • Credential Leakage
  • Related Test Cases
  • Remediation
  • Tools
  • References
  1. Web Application Security Testing
  2. Authorization Testing

Testing for OAuth Weaknesses (WSTG-ATHZ-05)

PreviousTesting for OAuth Client WeaknessesNextSession Management Testing

Last updated 2 years ago

ID

WSTG-ATHZ-05

Summary

(hereinafter referred to as OAuth) is an authorization framework that allows a client to access resources on the behalf of its user.

In order to achieve this, OAuth heavily relies on tokens to communicate between the different entities, each entity having a different :

  • Resource Owner: The entity who grants access to a resource, the owner, and in most cases is the user themselves

  • Client: The application that is requesting access to a resource on behalf of the Resource Owner. These clients come in two :

    • Public: clients that can't protect a secret (e.g. front-end focused applications, such as SPAs, mobile applications, etc.)

    • Confidential: clients that are able to securely authenticate with the authorization server by keeping their registered secrets safe (e.g. back-end services)

  • Authorization Server: The server that holds authorization information and grants the access

  • Resource Server: The application that serves the content accessed by the client

Since OAuth's responsibility is to delegate access rights by the owner to the client, this is a very attractive target for attackers, and bad implementations lead to unauthorized access to the users' resources and information.

In order to provide access to a client application, OAuth relies on several to generate an access token:

  • : used by both confidential and public clients to exchange an authorization code for an access token, but recommended only for confidential clients

  • : PKCE builds on top of the Authorization Code grant, providing stronger security for it to be used by public clients, and improving the posture of confidential ones

  • : used for machine to machine communication, where the "user" here is the machine requesting access to its own resources from the Resource Server

  • : used for devices with limited input capabilities.

  • : tokens provided by the authorization server to allow clients to refresh users' access tokens once they become invalid or expire. This grant type is used in conjunction with one other grant type.

Please note that OAuth flows are a complex topic, and the above includes only a summary of the key areas. The inline references contain further information about the specific flows.

Test Objectives

  • Determine if OAuth2 implementation is vulnerable or using a deprecated or custom implementation.

How to Test

Testing for Deprecated Grant Types

Deprecated grant types were obsoleted for security and functionality reasons. Identifying if they're being used allows us to quickly review if they're susceptible to any of the threats pertaining to their usage. Some might be out of scope to the attacker, such as the way a client might be using the users' credentials. This should be documented and raised to the internal engineering teams.

For public clients, it is generally possible to identify the grant type in the request to the /token endpoint. It is indicated in the token exchange with the parameter grant_type.

The following example shows the Authorization Code grant with PKCE.

POST /oauth/token HTTP/1.1
Host: as.example.com
[...]

{
  "client_id":"example-client",
  "code_verifier":"example",
  "grant_type":"authorization_code",
  "code":"example",
  "redirect_uri":"http://client.example.com"
}

The values for the grant_type parameter and the grant type they indicate are:

  • password: Indicates the ROPC grant.

  • client_credentials: Indicates the Client Credential grant.

  • authorization_code: Indicates the Authorization Code grant.

The Implicit Flow type is not indicated by the grant_type parameter since the token is presented in the response to the /authorization endpoint request, and instead can be identified through the response_type. Below is an example.

GET /authorize
  ?client_id=<some_client_id>
  &response_type=token 
  &redirect_uri=https%3A%2F%2Fclient.example.com%2F
  &scope=openid%20profile%20email
  &state=<random_state>

The following URL parameters indicate the OAuth flow being used:

  • response_type=token: Indicates Implicit Flow, as the client is directly requesting from the authorization server to return a token.

  • response_type=code: Indicates Authorization Code flow, as the client is requesting from the authorization server to return a code, that will be exchanged afterwards with a token.

  • code_challenge=sha256(xyz): Indicates the PKCE extension, as no other flow uses this parameter.

The following is an example authorization request for Authorization Code flow with PKCE:

GET /authorize
    ?redirect_uri=https%3A%2F%2Fclient.example.com%2F
    &client_id=<some_client_id>
    &scope=openid%20profile%20email
    &response_type=code
    &response_mode=query
    &state=<random_state>
    &nonce=<random_nonce>
    &code_challenge=<random_code_challenge>
    &code_challenge_method=S256 HTTP/1.1
Host: as.example.com
[...]

Public Clients

The Authorization Code grant with PKCE extension is recommended for public clients. An authorization request for Authorization Code flow with PKCE should contain response_type=code and code_challenge=sha256(xyz).

The token exchange should contain the grant type authorization_code and a code_verifier.

Improper grant types for public clients are:

  • Authorization Code grant without the PKCE extension

  • Client Credentials

  • Implicit Flow

  • ROPC

Confidential Clients

The Authorization Code grant is recommended for confidential clients. The PKCE extension may be used as well.

Improper grant types for confidential clients are:

  • Client Credentials (Except for machine-to-machine -- see below)

  • Implicit Flow

  • ROPC

Machine-to-Machine

In situations where no user interaction occurs and the clients are only confidential clients, the Client Credentials grant may be used.

If you know the client_id and client_secret, it is possible to obtain a token by passing the client_credentials grant type.

$ curl --request POST \
  --url https://as.example.com/oauth/token \
  --header 'content-type: application/json' \
  --data '{"client_id":"<some_client_id>","client_secret":"<some_client_secret>","grant_type":"client_credentials"}' --proxy http://localhost:8080/ -k

Credential Leakage

Depending on the flow, OAuth transports several types of credentials in as URL parameters.

The following tokens can be considered to be leaked credentials:

  • access token

  • refresh token

  • authorization code

  • PKCE code challenge / code verifier

The risk that's carried by the implicit flow leaking the tokens is far higher than leaking the code or any other code_* parameters, as they are bound to specific clients and are harder to abuse in case of leakage.

In order to test this scenario, make use of an HTTP intercepting proxy such as OWASP ZAP and intercept the OAuth traffic.

  • Step through the authorization process and identify any credentials present in the URL.

  • If any external resources are included in a page involved with the OAuth flow, analyze the request made to them. Credentials could be leaked in the referrer header.

After stepping through the OAuth flow and using the application, a few requests are captured in the request history of an HTTP intercepting proxy. Search for the HTTP referrer header (e.g. Referer: https://idp.example.com/) containing the authorization server and client URL in the request history.

Related Test Cases

Remediation

  • When implementing OAuth, always consider the technology used and whether the application is a server-side application that can avoid revealing secrets, or a client-side application that cannot.

  • In almost any case, use the Authorization Code flow with PKCE. One exception may be machine-to-machine flows.

  • Use POST parameters or header values to transport secrets.

  • When no other possibilities exists (for example, in legacy applications that can not be migrated), implement additional security headers such as a Referrer-Policy.

Tools

References

Two flows will be deprecated in the release of , and their usage is not recommended:

: PKCE's secure implementation renders this flow obsolete. Prior to PKCE, the implicit flow was used by client-side applications such as since relaxed the for websites to inter-communicate. For more information on why the implicit grant is not recommended, review this .

:used to exchange users' credentials directly with the client, which then sends them to the authorization to exchange them for an access token. For information on why this flow is not recommended, review this .

*: The implicit flow in OAuth only is deprecated, yet is still a viable solution within Open ID Connect (OIDC) to retrieve id_tokens. Be careful to understand how the implicit flow is being used, which can be identified if only the /authorization endpoint is being used to gain an access token, without relying on /token endpoint in any way. An example on this can be found .

Due to how OAuth works, the authorization code as well as the code_challenge, and code_verifier may be part of the URL. The implicit flow transports the authorization token as part of the URL if the response_mode is not set to . This may lead to leakage of the requested token or code in the referrer header, in log files, and proxies due to these parameters being passed either in the query or the fragment.

Reviewing the HTML meta tags (although this tag is on all browsers), or the could help assess if any credential leakage is happening through the referrer header.

OAuth2.0
role
types
authorization grant types
Authorization Code
Proof Key for Code Exchange (PKCE)
Client Credentials
Device Code
Refresh Token
OAuth2.1
Implicit Flow*
single page applications
CORS
same-origin policy
section
Resource Owner Password Credentials
section
here
form_post
not supported
Referrer-Policy
Testing JSON Web Tokens
BurpSuite
EsPReSSO
OWASP ZAP
User Authentication with OAuth 2.0
The OAuth 2.0 Authorization Framework
The OAuth 2.0 Authorization Framework: Bearer Token Usage
OAuth 2.0 Threat Model and Security Considerations
OAuth 2.0 Security Best Current Practice
Authorization Code Flow with Proof Key for Code Exchange