RFC 6819

OAuth 2.0 Threat Model and Security Considerations

πŸ“… published January 2013, from ietf

OAuth 2.0 Threat Model and Security Considerations πŸŽ€

Okay bestie, this is part 1 of 14 πŸ’– It's the intro stuff: who wrote it, what kind of doc it is, and the table of contents, so you know the map before we dive in πŸ—ΊοΈβœ¨

  • RFC number: 6819
  • Category: Informational (not a standards-track spec, just published for info πŸ“š)
  • ISSN: 2070-1721
  • Date: January 2013
  • Authors: T. Lodderstedt, Ed. (Deutsche Telekom AG), M. McGloin (IBM), and P. Hunt (Oracle Corporation) πŸ‘―β€β™€οΈ
  • Obsoletes / Updates: the title block doesn't list anything it obsoletes or updates πŸ™…β€β™€οΈ

Abstract ✨

So this doc is basically the extra security tea for OAuth πŸ«– It adds security considerations on top of what the OAuth 2.0 spec already covers. The whole thing is built on a really thorough threat model for OAuth 2.0 πŸ’…


Status of This Memo 🌸

Real talk, this one is not a standards-track spec. It's published for informational purposes only πŸ“–

It's still an IETF product πŸ›οΈ and it reflects what the IETF community agrees on. It got public review and the IESG (the Internet Engineering Steering Group) approved it for publication 🫢 But being IESG-approved doesn't automatically make something a candidate for any level of Internet Standard, so don't get it twisted. Check out Section 2 of RFC 5741 for that 🧐

If you want the latest status, errata, or a place to leave feedback, head to http://www.rfc-editor.org/info/rfc6819 πŸ¦‹


Copyright (c) 2013 IETF Trust and the persons identified as the document authors. All rights reserved. πŸ”’

This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can read at http://trustee.ietf.org/license-info (as they stood when this was published) πŸ“œ Please actually read those, bestie, because they spell out your rights and restrictions with this doc πŸ™ˆ

One important bit: any Code Components you pull out of this doc have to include the Simplified BSD License text, like it's described in Section 4.e of the Trust Legal Provisions. They also come with no warranty, same as described in the Simplified BSD License 🌈


Table of Contents 🧚

1. Introduction ....................................................6
2. Overview ........................................................7
   2.1. Scope ......................................................7
   2.2. Attack Assumptions .........................................7
   2.3. Architectural Assumptions ..................................8
        2.3.1. Authorization Servers ...............................8
        2.3.2. Resource Server .....................................9
        2.3.3. Client ..............................................9
3. Security Features ...............................................9
   3.1. Tokens ....................................................10
        3.1.1. Scope ..............................................11
        3.1.2. Limited Access Token Lifetime ......................11
   3.2. Access Token ..............................................11
   3.3. Refresh Token .............................................11
   3.4. Authorization "code" ......................................12
   3.5. Redirect URI ..............................................13
   3.6. "state" Parameter .........................................13
   3.7. Client Identifier .........................................13
4. Threat Model ...................................................15
   4.1. Clients ...................................................16
        4.1.1. Threat: Obtaining Client Secrets ...................16
        4.1.2. Threat: Obtaining Refresh Tokens ...................17
        4.1.3. Threat: Obtaining Access Tokens ....................19
        4.1.4. Threat: End-User Credentials Phished Using
               Compromised or Embedded Browser ....................19
        4.1.5. Threat: Open Redirectors on Client .................20
   4.2. Authorization Endpoint ....................................21
        4.2.1. Threat: Password Phishing by Counterfeit
               Authorization Server ...............................21
        4.2.2. Threat: User Unintentionally Grants Too
               Much Access Scope ..................................21
        4.2.3. Threat: Malicious Client Obtains Existing
               Authorization by Fraud .............................22
        4.2.4. Threat: Open Redirector ............................22
   4.3. Token Endpoint ............................................23
        4.3.1. Threat: Eavesdropping Access Tokens ................23
        4.3.2. Threat: Obtaining Access Tokens from
               Authorization Server Database ......................23
        4.3.3. Threat: Disclosure of Client Credentials
               during Transmission ................................23
        4.3.4. Threat: Obtaining Client Secret from
               Authorization Server Database ......................24
        4.3.5. Threat: Obtaining Client Secret by Online Guessing .24

   4.4. Obtaining Authorization ...................................25
        4.4.1. Authorization "code" ...............................25
               4.4.1.1. Threat: Eavesdropping or Leaking
                        Authorization "codes" .....................25
               4.4.1.2. Threat: Obtaining Authorization "codes"
                        from Authorization Server Database ........26
               4.4.1.3. Threat: Online Guessing of
                        Authorization "codes" .....................27
               4.4.1.4. Threat: Malicious Client Obtains
                        Authorization .............................27
               4.4.1.5. Threat: Authorization "code" Phishing .....29
               4.4.1.6. Threat: User Session Impersonation ........29
               4.4.1.7. Threat: Authorization "code" Leakage
                        through Counterfeit Client ................30
               4.4.1.8. Threat: CSRF Attack against redirect-uri ..32
               4.4.1.9. Threat: Clickjacking Attack against
                        Authorization .............................33
               4.4.1.10. Threat: Resource Owner Impersonation .....33
               4.4.1.11. Threat: DoS Attacks That Exhaust
                         Resources ................................34
               4.4.1.12. Threat: DoS Using Manufactured
                         Authorization "codes" ....................35
               4.4.1.13. Threat: Code Substitution (OAuth Login) ..36
        4.4.2. Implicit Grant .....................................37
               4.4.2.1. Threat: Access Token Leak in
                        Transport/Endpoints .......................37
               4.4.2.2. Threat: Access Token Leak in
                        Browser History ...........................38
               4.4.2.3. Threat: Malicious Client Obtains
                        Authorization .............................38
               4.4.2.4. Threat: Manipulation of Scripts ...........38
               4.4.2.5. Threat: CSRF Attack against redirect-uri ..39
               4.4.2.6. Threat: Token Substitution (OAuth Login) ..39
        4.4.3. Resource Owner Password Credentials ................40
               4.4.3.1. Threat: Accidental Exposure of
                        Passwords at Client Site ..................41
               4.4.3.2. Threat: Client Obtains Scopes
                        without End-User Authorization ............42
               4.4.3.3. Threat: Client Obtains Refresh
                        Token through Automatic Authorization .....42
               4.4.3.4. Threat: Obtaining User Passwords
                        on Transport ..............................43
               4.4.3.5. Threat: Obtaining User Passwords
                        from Authorization Server Database ........43
               4.4.3.6. Threat: Online Guessing ...................43
        4.4.4. Client Credentials .................................44

   4.5. Refreshing an Access Token ................................44
        4.5.1. Threat: Eavesdropping Refresh Tokens from
               Authorization Server ...............................44
        4.5.2. Threat: Obtaining Refresh Token from
               Authorization Server Database ......................44
        4.5.3. Threat: Obtaining Refresh Token by Online
               Guessing ...........................................45
        4.5.4. Threat: Refresh Token Phishing by
               Counterfeit Authorization Server ...................45
   4.6. Accessing Protected Resources .............................46
        4.6.1. Threat: Eavesdropping Access Tokens on Transport ...46
        4.6.2. Threat: Replay of Authorized Resource
               Server Requests ....................................46
        4.6.3. Threat: Guessing Access Tokens .....................46
        4.6.4. Threat: Access Token Phishing by
               Counterfeit Resource Server ........................47
        4.6.5. Threat: Abuse of Token by Legitimate
               Resource Server or Client ..........................48
        4.6.6. Threat: Leak of Confidential Data in HTTP Proxies ..48
        4.6.7. Threat: Token Leakage via Log Files and
               HTTP Referrers .....................................48
5. Security Considerations ........................................49
   5.1. General ...................................................49
        5.1.1. Ensure Confidentiality of Requests .................49
        5.1.2. Utilize Server Authentication ......................50
        5.1.3. Always Keep the Resource Owner Informed ............50
        5.1.4. Credentials ........................................51
               5.1.4.1. Enforce Credential Storage
                        Protection Best Practices .................51
               5.1.4.2. Online Attacks on Secrets .................52
        5.1.5. Tokens (Access, Refresh, Code) .....................53
               5.1.5.1. Limit Token Scope .........................53
               5.1.5.2. Determine Expiration Time .................54
               5.1.5.3. Use Short Expiration Time .................54
               5.1.5.4. Limit Number of Usages or One-Time Usage ..55
               5.1.5.5. Bind Tokens to a Particular
                        Resource Server (Audience) ................55
               5.1.5.6. Use Endpoint Address as Token Audience ....56
               5.1.5.7. Use Explicitly Defined Scopes for
                        Audience and Tokens .......................56
               5.1.5.8. Bind Token to Client id ...................56
               5.1.5.9. Sign Self-Contained Tokens ................56
               5.1.5.10. Encrypt Token Content ....................56
               5.1.5.11. Adopt a Standard Assertion Format ........57
        5.1.6. Access Tokens ......................................57

1. Introduction ✨

Okay bestie, this document is the extra security homework for OAuth, on top of what the OAuth spec already covers πŸ’… It's built on a seriously thorough threat model for the OAuth 2.0 protocol [RFC6749] πŸ”₯ Here's what's inside:

  • Documents any assumptions and scope considered when creating the threat model. πŸ“
  • Describes the security features built into the OAuth protocol and how they're meant to thwart attacks. πŸ›‘οΈ
  • Gives a comprehensive threat model for OAuth and describes the countermeasures for each threat. 🧚

Threats include intentional attacks on OAuth tokens and on the resources those tokens protect 😀 They also include security risks that show up when the proper security measures aren't put in place πŸ’€ The threats are organized around the protocol's structure so dev teams can lock down each part properly πŸŽ€ So you get all the threats for granting access in one place, all the threats for a particular grant type in one place, and all the threats for protecting the resource server in one place 🌈

Note: Okay, this document can't assess the probability or the risk of a particular threat, because those depend totally on the app and deployment that OAuth is protecting πŸ™ˆ The impacts are also described pretty abstractly. But the info here can be a foundation for deployment-specific threat models ✨ Implementers can refine and detail the abstract threat model to account for their own deployment's properties and come up with a risk analysis πŸ’œ And since this document builds on the base OAuth 2.0 specification, it doesn't consider proposed extensions like client registration or discovery, many of which are still under discussion 🫢

2. Overview πŸ¦‹

2.1. Scope πŸŽ€

Okay so this security considerations doc only looks at clients that are bound to a particular deployment, as supported by [RFC6749] πŸ’– These deployments have the following vibes:

  • Resource server URLs are static and well-known at development time 🌸 Authorization server URLs can be static or discovered πŸ”
  • Token scope values (like applicable URLs and methods) are well-known at development time πŸ“
  • Client registration is out of scope of the current core specification πŸ™ƒ So this document assumes a broad variety of options, from static registration during development time all the way to dynamic registration at runtime 🌈

The following are considered out of scope, sorry not sorry πŸ™…β€β™€οΈ

  • Communication between the authorization server and resource server. πŸ”’
  • Token formats. 🎫
  • Except for the resource owner password credentials grant type (see [RFC6749], Section 4.3), the mechanism the authorization server uses to authenticate the user. πŸ™ˆ
  • The mechanism by which a user obtained an assertion, and any resulting attacks mounted because the assertion was false. πŸ₯²
  • Clients not bound to a specific deployment. An example would be a mail client with support for contact list access via the Portable Contacts API (see [Portable-Contacts]). These clients can't be registered upfront with a particular deployment, so they should dynamically discover the URLs relevant for the OAuth protocol. 🧭

2.2. Attack Assumptions 😈

These assumptions are about an attacker and the resources available to them. It is assumed that:

  • The attacker has full access to the network between the client and the authorization server, and between the client and the resource server. The attacker may eavesdrop on any communications between those parties. The attacker is not assumed to have access to communication between the authorization server and the resource server. πŸ‘€
  • An attacker has unlimited resources to mount an attack. πŸ€‘
  • Two of the three parties involved in the OAuth protocol may collude to mount an attack against the third party. For example, the client and authorization server may be under the control of an attacker and collude to trick a user into gaining access to resources. 🚨 Literally the villain arc nobody asked for πŸ’€

2.3. Architectural Assumptions πŸ—οΈ

This section documents assumptions about the features, limitations, and design options of the different entities in an OAuth deployment πŸ’… It also covers the security-sensitive data elements those entities manage ✨ These assumptions are the foundation of the threat analysis, so pay attention bestie 🧐

The OAuth protocol gives deployments a certain degree of freedom in how they implement and apply the standard 🌷 The core specification defines the core concepts of an authorization server and a resource server πŸŽ€ Both servers can live in the same server entity, or they can be different entities 🫧 The latter is typically the case for multi-service providers with a single authentication and authorization system, and it's more typical in middleware architectures 🧩

2.3.1. Authorization Servers πŸ‘‘

The following data elements are stored or accessible on the authorization server:

  • Usernames and passwords πŸ”‘
  • Client IDs and secrets 🀫
  • Client-specific refresh tokens πŸ”„
  • Client-specific access tokens (in the case of a handle-based design; see Section 3.1) 🎟️
  • HTTPS certificate/key πŸ”
  • Per-authorization process (in the case of a handle-based design; Section 3.1): redirect_uri, client_id, and authorization code πŸ“¦

2.3.2. Resource Server πŸ—„οΈ

The following data elements are stored or accessible on the resource server:

  • User data (out of scope) πŸ™…β€β™€οΈ
  • HTTPS certificate/key πŸ”
  • Either authorization server credentials (handle-based design; see Section 3.1) or authorization server shared secret/public key (assertion-based design; see Section 3.1) πŸ—οΈ
  • Access tokens (per request) 🎫

It is assumed that a resource server has no knowledge of refresh tokens, user passwords, or client secrets πŸ™Œ Very trust-issues energy, and honestly I respect it πŸ’…

2.3.3. Client πŸ“±

In OAuth, a client is an application making protected resource requests on behalf of the resource owner and with its authorization 🫢 There are different types of clients with different implementation and security characteristics, like web, user-agent-based, and native applications 🌐 A full definition of the different client types and profiles is given in [RFC6749], Section 2.1 πŸ“–

The following data elements are stored or accessible on the client:

  • Client ID (and client secret or corresponding client credential) πŸͺͺ
  • One or more refresh tokens (persistent) and access tokens (transient) per end user or other security context or delegation context πŸ”
  • Trusted certification authority (CA) certificates (HTTPS) πŸ“œ
  • Per-authorization process: redirect_uri, and authorization code 🧾

3. Security Features πŸ›‘οΈ

These are some of the security features that have been built into the OAuth 2.0 protocol to mitigate attacks and security issues. Main character energy for sure πŸ‘‘πŸŒˆ

3.1. Tokens πŸŽ€

okay so OAuth makes SO many kinds of tokens 🫢 (access tokens, refresh tokens, authorization "codes"), and the information inside a token can be represented in two ways, bestie:

Handle (or artifact) 🧚 A 'handle' is a reference to some internal data structure within the authorization server. That data structure holds the attributes of the token, like user id (UID), scope, etc. Handles enable simple revocation and do not require cryptographic mechanisms to protect token content from being modified. On the other hand, handles require communication between the issuing and consuming entity (e.g., the authorization server and resource server) in order to validate the token and obtain token-bound data. This communication might have a negative impact on performance and scalability if both entities reside on different systems. Handles are therefore typically used if the issuing and consuming entity are the same. A 'handle' token is often referred to as an 'opaque' token because the resource server does not need to be able to interpret the token directly; it simply uses the token. πŸ’…

Assertion (aka self-contained token) ✨ An assertion is a parseable token. It typically has a duration, has an audience, and is digitally signed in order to ensure data integrity and origin authentication. It contains information about the user and the client. Examples of assertion formats are Security Assertion Markup Language (SAML) assertions [OASIS.saml-core-2.0-os] and Kerberos tickets [RFC4120]. Assertions can typically be directly validated and used by a resource server without interactions with the authorization server. This results in better performance and scalability in deployments where the issuing and consuming entities reside on different systems. Implementing token revocation is more difficult with assertions than with handles. not a fan of that one tbh 😭

Tokens can be used in two ways to invoke requests on resource servers, as follows:

Bearer token 🌸 A 'bearer token' is a token that can be used by any client who has received the token (e.g., [RFC6750]). Because mere possession is enough to use the token, it is important that communication between endpoints be secured to ensure that only authorized endpoints may capture the token. The bearer token is convenient for client applications, as it does not require them to do anything to use them (such as a proof of identity). Bearer tokens have similar characteristics to web single-sign-on (SSO) cookies used in browsers. πŸ“

Proof token πŸ” A 'proof token' is a token that can only be used by a specific client. Each use of the token requires the client to perform some action that proves that it is the authorized user of the token. Examples of this are MAC-type access tokens, which require the client to digitally sign the resource request with a secret corresponding to the particular token sent with the request (e.g., [OAuth-HTTP-MAC]). this is giving main character security energy πŸ‘‘

3.1.1. Scope πŸ¦‹

A scope represents the access authorization associated with a particular token with respect to resource servers, resources, and methods on those resources. Scopes are the OAuth way to explicitly manage the power associated with an access token. A scope can be controlled by the authorization server and/or the end user in order to limit access to resources for OAuth clients that these parties deem less secure or trustworthy. Optionally, the client can request the scope to apply to the token but only for a lesser scope than would otherwise be granted, e.g., to reduce the potential impact if this token is sent over non-secure channels. A scope is typically complemented by a restriction on a token's lifetime. ✨

3.1.2. Limited Access Token Lifetime ⏳

The protocol parameter expires_in allows an authorization server (based on its policies or on behalf of the end user) to limit the lifetime of an access token and to pass this information to the client. This mechanism can be used to issue short-lived tokens to OAuth clients that the authorization server deems less secure, or where sending tokens over non-secure channels. 🫢

3.2. Access Token πŸ”‘

An access token is used by a client to access a resource. Access tokens typically have short life spans (minutes or hours) that cover typical session lifetimes. An access token may be refreshed through the use of a refresh token. The short lifespan of an access token, in combination with the usage of refresh tokens, enables the possibility of passive revocation of access authorization on the expiry of the current access token. πŸ’–

3.3. Refresh Token πŸ”„

A refresh token represents a long-lasting authorization of a certain client to access resources on behalf of a resource owner. Such tokens are exchanged between the client and authorization server only. Clients use this kind of token to obtain ("refresh") new access tokens used for resource server invocations. 🌈

A refresh token, coupled with a short access token lifetime, can be used to grant longer access to resources without involving end-user authorization. This offers an advantage where resource servers and authorization servers are not the same entity, e.g., in a distributed environment, as the refresh token is always exchanged at the authorization server. The authorization server can revoke the refresh token at any time, causing the granted access to be revoked once the current access token expires. Because of this, a short access token lifetime is important if timely revocation is a high priority. 🚨

The refresh token is also a secret bound to the client identifier and client instance that originally requested the authorization; the refresh token also represents the original resource owner grant. This is ensured by the authorization process as follows:

  1. The resource owner and user agent safely deliver the authorization "code" to the client instance in the first place.
  2. The client uses it immediately in secure transport-level communications to the authorization server and then securely stores the long-lived refresh token.
  3. The client always uses the refresh token in secure transport-level communications to the authorization server to get an access token (and optionally roll over the refresh token).

So, as long as the confidentiality of the particular token can be ensured by the client, a refresh token can also be used as an alternative means to authenticate the client instance itself. πŸ”βœ¨

3.4. Authorization "code" 🎫

An authorization "code" represents the intermediate result of a successful end-user authorization process and is used by the client to obtain access and refresh tokens. Authorization "codes" are sent to the client's redirect URI instead of tokens for two purposes:

  1. Browser-based flows expose protocol parameters to potential attackers via URI query parameters (HTTP referrer), the browser cache, or log file entries, and could be replayed. In order to reduce this threat, short-lived authorization "codes" are passed instead of tokens and exchanged for tokens over a more secure direct connection between the client and the authorization server. πŸ™ˆ
  2. It is much simpler to authenticate clients during the direct request between the client and the authorization server than in the context of the indirect authorization request. The latter would require digital signatures.

3.5. Redirect URI 🚦

A redirect URI helps to detect malicious clients and prevents phishing attacks from clients attempting to trick the user into believing the phisher is the client. The value of the actual redirect URI used in the authorization request has to be presented and is verified when an authorization "code" is exchanged for tokens. This helps to prevent attacks where the authorization "code" is revealed through redirectors and counterfeit web application clients. The authorization server should require public clients and confidential clients using the implicit grant type to pre-register their redirect URIs and validate against the registered redirect URI in the authorization request. πŸ’€

3.6. "state" Parameter 🧁

The state parameter is used to link requests and callbacks to prevent cross-site request forgery attacks (see Section 4.4.1.8) where an attacker authorizes access to his own resources and then tricks a user into following a redirect with the attacker's token. This parameter should bind to the authenticated state in a user agent and, as per the core OAuth spec, the user agent must be capable of keeping it in a location accessible only by the client and user agent, i.e., protected by same-origin policy. the state param is literally the bouncer at the door πŸŒˆπŸ’…

3.7. Client Identifier ✨

Okay so, authentication protocols have historically not cared about which software is acting for the end user πŸ‘€. OAuth does care, bestie πŸ’…. That helps raise the security level in delegated authorization scenarios, and it matters because the client can act even when the user isn't around 🫢.

OAuth uses the client identifier to group related requests together so they trace back to the same originator, like:

  • a particular end-user authorization process and the matching request to the token endpoint that exchanges the authorization code for tokens, or
  • the first authorization and token issuance by an end user to a particular client, plus later requests from that client to get tokens without user consent (automatic processing of repeated authorizations)

The authorization server can also use this identifier to show a user relevant registration info when it asks for consent to a scope requested by a particular client πŸŽ€. The client identifier can be used to cap how many requests a client makes, or to charge the client per request πŸ’°. It's also handy for telling clients apart, for example in server log files πŸ“œ.

OAuth defines two client types, confidential and public, based on whether they can authenticate with the authorization server (in other words, whether they can keep their client credentials confidential) πŸ”. Confidential clients can keep their client credentials confidential (meaning a client secret tied to the client identifier), or they can do secure client authentication another way, like a client assertion (e.g., SAML) or key cryptography. Key cryptography is considered the more secure option πŸ”‘.

The authorization server should figure out whether the client can keep its secret confidential or use secure authentication πŸ•΅οΈβ€β™€οΈ. The alternative is that the end user verifies the client's identity, e.g., by only installing trusted applications πŸ“². The redirect URI can help stop credentials from being sent to a counterfeit client after end-user authorization in some cases, but it can't be used to verify the client identifier 🚫.

Clients can be categorized based on client type, profile (e.g., native vs. web application; see [RFC6749], Section 9), and deployment model πŸ—‚οΈ:

Deployment-independent client_id with pre-registered redirect_uri and without client_secret: This identifier is shared by multiple installs of the same software package πŸ“¦. The identifier can only be validated with help from the end user. It's a viable option for native applications, since it lets you show meta info about the client to the user and tell clients apart in log files. Revoking the rights tied to this client identifier will affect ALL deployments of the software πŸ’€.

Deployment-independent client_id with pre-registered redirect_uri and with client_secret: This is only an option for native applications, because web applications would need different redirect URIs πŸ“±. It's not advisable, since the client secret can't be protected properly (see Section 4.1.1) 😬. Because of those security weaknesses, these client identities have the same trust level as deployment-independent clients without secrets. Revocation will affect ALL deployments.

Deployment-specific client_id with pre-registered redirect_uri and with client_secret: The client registration process checks the client's properties, like redirect URI, web site URL, web site name, and contacts 🧐. This kind of client identifier works for all the relevant use cases mentioned above πŸ™Œ. Web applications can reach this level with a manual or user-bound registration process. Native applications find it much harder. Either an administrator installs the application and checks that it's authentic, or a single entity controls the whole process, from validating the app to installing it on the device and creating the client credentials (e.g., an application market provider) πŸͺ. Revocation will affect a single deployment only ✨.

Deployment-specific client_id with client_secret without validated properties: The authorization server can recognize this kind of client across later requests (e.g., authorization and token issuance, refresh token issuance, and access token refreshment) πŸ”. The authorization server can't guarantee any property of the client to end users πŸ€·β€β™€οΈ. Automatic processing of re-authorizations could be allowed too. These client credentials can be generated automatically without validating any client properties, which makes this another option, especially for native applications πŸ“². Revocation will affect a single deployment only πŸ¦‹.


4. Threat Model πŸ•΅οΈβ€β™€οΈ

This section gives a full threat model of OAuth 2.0 πŸ”₯. The threats are grouped first by attacks aimed at an OAuth component (the client, authorization server, and resource server), and then by flow, like obtaining a token or accessing protected resources πŸ—ΊοΈ. Every countermeasure description points to a detailed description in Section 5 πŸ“–.

4.1. Clients πŸ“±

This section describes possible threats aimed at OAuth clients 🎯.

4.1.1. Threat: Obtaining Client Secrets πŸ”

The attacker could try to get the secret of a particular client so they can:

  • replay its refresh tokens and authorization codes, or
  • obtain tokens on behalf of the attacked client, with the privileges of that client_id, acting as an instance of the client 😈.

The resulting impact would be the following:

  • Client authentication to the authorization server can be bypassed 🚨.
  • Stolen refresh tokens or authorization codes can be replayed πŸ”.

Depending on the client category, the following attacks could be used to get the client secret πŸ‘€.

Attack: Obtain Secret From Source Code or Binary:

This applies to all client types 🌍. For open source projects, secrets can be pulled straight out of source code in public repositories πŸ’». Secrets can be extracted from application binaries just as easily when the published source isn't available to the attacker πŸ“¦. Even if an application goes to great lengths to obfuscate secrets in its distribution, keep in mind that anyone with a complete working application bundle or binary can still reverse-engineer the secret πŸ•΅οΈβ€β™€οΈ.

Countermeasures:

  • Don't issue secrets to public clients or to clients with inappropriate security policy (Section 5.2.3.1) πŸ™…β€β™€οΈ.
  • Require user consent for public clients (Section 5.2.3.2) βœ….
  • Use deployment-specific client secrets (Section 5.2.3.4) πŸŽ€.
  • Revoke client secrets (Section 5.2.3.6) 🧹.

Attack: Obtain a Deployment-Specific Secret:

An attacker may try to get the secret from a client installation, either from a web site (web server) or from a particular device (native application) 🎯.

Countermeasures:

  • Web server: Apply standard web server protection measures (for config files and databases) (see Section 5.3.2) πŸ›‘οΈ.
  • Native applications: Store secrets in secure local storage (Section 5.3.3) πŸ”’.
  • Revoke client secrets (Section 5.2.3.6) 🧹.

4.1.2. Threat: Obtaining Refresh Tokens πŸ”„

Depending on the client type, there are different ways refresh tokens can be revealed to an attacker 😱. The sub-sections below give a more detailed look at the different attacks for each client type, plus some specialized countermeasures. Before we get into those threats, here are some generally applicable countermeasures πŸ’–:

  • The authorization server should validate the client id associated with the particular refresh token with every refresh request (Section 5.2.2.2) πŸ‘€.
  • Limit token scope (Section 5.1.5.1) πŸ“.
  • Revoke refresh tokens (Section 5.2.2.4) 🧹.
  • Revoke client secrets (Section 5.2.3.6) 🧹.
  • Refresh tokens can automatically be replaced to detect unauthorized token usage by another party (see "Refresh Token Rotation", Section 5.2.2.3) πŸ”πŸ•΅οΈβ€β™€οΈ.

Attack: Obtain Refresh Token from Web Application:

An attacker may obtain the refresh tokens issued to a web application by getting past the web server's security controls 🏰.

Impact: Since a web application manages the user accounts of a certain site, this attack would expose all refresh tokens on that site to the attacker 😭.

Countermeasures:

  • Standard web server protection measures (Section 5.3.2) πŸ›‘οΈ.
  • Use strong client authentication (e.g., client_assertion/client_token) so the attacker can't get the client secret needed to exchange the tokens (Section 5.2.3.7) πŸ’ͺ.

Attack: Obtain Refresh Token from Native Clients:

On native clients, a leaked refresh token typically affects only a single user πŸ™‚.

Read from local file system: The attacker could try to get file system access on the device and read the refresh tokens πŸ“‚. They could use a malicious application to do that πŸ‘Ύ.

Countermeasures:

  • Store secrets in secure storage (Section 5.3.3) πŸ”’.
  • Use the device lock to prevent unauthorized device access (Section 5.3.4) πŸ”.

Attack: Steal Device:

The host device (e.g., a mobile phone) may be stolen πŸ“±πŸ’¨. If that happens, the attacker gets access to all applications under the legitimate user's identity 😱.

Countermeasures:

  • Use the device lock to prevent unauthorized device access (Section 5.3.4) πŸ”.
  • If a user knows the device has been stolen, they can revoke the affected tokens (Section 5.2.2.4) 🧹.

Attack: Clone Device:

All device data and applications get copied to another device, and the applications run as-is on the target device πŸ‘―β€β™€οΈ.

Countermeasures:

  • Use the device lock to prevent unauthorized device access (Section 5.3.4) πŸ”.
  • Combine the refresh token request with device identification (Section 5.2.2.5) πŸͺͺ.
  • Refresh token rotation (Section 5.2.2.3) πŸ”.
  • If a user knows the device has been cloned, they can use refresh token revocation (Section 5.2.2.4) 🧹.

4.1.3. Threat: Obtaining Access Tokens 🎟️

Depending on the client type, there are different ways access tokens can be revealed to an attacker πŸ‘€. Access tokens could be stolen from the device if the application stores them in a storage location that other applications can access 🚨.

Impact: When the token is a bearer token and no additional mechanism is used to identify the client, the attacker can access all resources associated with the token and its scope πŸ’€.

Countermeasures:

  • Keep access tokens in transient memory and limit grants (Section 5.1.6) 🧠.
  • Limit token scope (Section 5.1.5.1) πŸ“.
  • Keep access tokens in private memory or apply the same protection means as for refresh tokens (Section 5.2.2) πŸ”’.
  • Keep the access token lifetime short (Section 5.1.5.3) ⏱️.

4.1.4. Threat: End-User Credentials Phished Using Compromised or Embedded Browser 🎭

okay bestie, picture this: a sneaky app tries to phish people's passwords by messing with an embedded browser during the end-user authorization process, or by showing its own login screen instead of letting a trusted system browser draw the authorization UI. 😈 when that happens, the usual visual trust signals (like TLS confirmation and website security mechanisms) can get bypassed. and if the client app is running its own embedded or internal UI, it gets access to extra info it should not have, like UID/password. not it. πŸ™…β€β™€οΈ

Impact: if the client application or the communication is compromised, the user would not be aware of this, and all information in the authorization exchange, such as username and password, could be captured. πŸ’€

Countermeasures:

  • the OAuth flow is designed so that client applications never need to know user passwords. client applications should avoid directly asking users for their credentials. πŸ” also, end users could be educated about phishing attacks and best practices, such as only accessing trusted clients. OAuth does not provide any protection against malicious applications, and the end user is solely responsible for the trustworthiness of any native application installed. main character energy, but make it responsible 🌈
  • client applications could be validated prior to publication in an application market for users to access. that validation is out of scope for OAuth, but it could include validating that the client application handles user authentication in an appropriate way. ✨
  • client developers should not write client applications that collect authentication information directly from users. they should instead delegate this task to a trusted system component, e.g., the system browser. πŸ¦‹

4.1.5. Threat: Open Redirectors on Client πŸͺ€

an open redirector is an endpoint that uses a parameter to automatically redirect a user agent to the location specified by the parameter value, without any validation. so, bestie, if the authorization server only lets the client register part of its redirect URI, an attacker can use an open redirector run by the client to build a redirect URI that still passes the authorization server's validation. 😭 then the authorization "code" or access token gets sent to an endpoint the attacker controls. not slay.

Impact: an attacker could gain access to authorization "codes" or access tokens. 🚨

Countermeasures:

  • require clients to register the full redirect URI (Section 5.2.3.5). πŸŽ€

4.2. Authorization Endpoint ✨

4.2.1. Threat: Password Phishing by Counterfeit Authorization Server πŸ•΅οΈβ€β™€οΈ

okay so OAuth makes no attempt to verify the authenticity of the authorization server. 😬 a hostile party could take advantage of this by intercepting the client's requests and sending back misleading or otherwise incorrect responses. this could be done with DNS or Address Resolution Protocol (ARP) spoofing. and because OAuth and similar protocols are so widely deployed, users may get so used to being redirected to websites where they're asked to enter their passwords that they stop checking. if users aren't careful about verifying these sites before typing in their credentials, attackers can totally exploit that habit to steal passwords. πŸ’”

Countermeasures:

  • authorization servers should consider such attacks when developing services based on OAuth. they should require the use of transport-layer security for any requests where the authenticity of the authorization server or of request responses is an issue (see Section 5.1.2). πŸ”’
  • authorization servers should try to educate users about the risks posed by phishing attacks. they should also provide mechanisms that make it easy for users to confirm the authenticity of their sites. 🧚

4.2.2. Threat: User Unintentionally Grants Too Much Access Scope 🫣

when obtaining end-user authorization, the end user may not understand the scope of the access being granted, or who it's being granted to. they might also end up giving a client access to resources that should not be permitted. πŸ˜΅β€πŸ’«

Countermeasures:

  • explain the scope (resources and the permissions) the user is about to grant in an understandable way (Section 5.2.4.2). πŸ“–
  • narrow the scope, based on the client. when obtaining end-user authorization, and where the client requests scope, the authorization server may want to consider whether to honor that scope based on the client identifier. that decision is between the client and authorization server and is outside the scope of this spec. the authorization server may also want to consider what scope to grant based on the client type, e.g., providing lower scope to public clients (Section 5.1.5.1). πŸ“

4.2.3. Threat: Malicious Client Obtains Existing Authorization by Fraud 🎭

authorization servers may want to automatically process authorization requests from clients the user has already authorized. so when the user gets redirected to the authorization server's end-user authorization endpoint, and the server detects they've already granted access to that particular client, it skips the approval prompt and automatically redirects the user back to the client. ⚑

but a malicious client could totally exploit that feature and try to grab an authorization "code" instead of the legitimate client. πŸ‘€

Countermeasures:

  • authorization servers should not automatically process repeat authorizations to public clients unless the client is validated using a pre-registered redirect URI (Section 5.2.3.5). πŸ›‘
  • authorization servers can reduce the risks linked to automatic processing by limiting the scope of access tokens obtained through automated approvals (Section 5.1.5.1). 🧁

4.2.4. Threat: Open Redirector πŸšͺ

an attacker could use the end-user authorization endpoint and the redirect URI parameter to abuse the authorization server as an open redirector. an open redirector is an endpoint that uses a parameter to automatically redirect a user agent to the location specified by the parameter value, without any validation. 😀

Impact: an attacker could use a user's trust in an authorization server to launch a phishing attack. 🎣

Countermeasures:

  • require clients to register any full redirect URIs (Section 5.2.3.5). πŸ“
  • don't redirect to a redirect URI if the client identifier or redirect URI can't be verified (Section 5.2.3.5). πŸ™…β€β™€οΈ

4.3. Token Endpoint 🌸

4.3.1. Threat: Eavesdropping Access Tokens πŸ‘‚

attackers may try to eavesdrop on access tokens in transit from the authorization server to the client. 🫣

Impact: the attacker is able to access all resources with the permissions covered by the scope of the particular access token. πŸ’€

Countermeasures:

  • as per the core OAuth spec, the authorization servers must ensure that these transmissions are protected using transport-layer mechanisms such as TLS (see Section 5.1.1). πŸ”
  • if end-to-end confidentiality cannot be guaranteed, reducing scope (see Section 5.1.5.1) and expiry time (Section 5.1.5.3) for access tokens can be used to reduce the damage in case of leaks. ⏳

4.3.2. Threat: Obtaining Access Tokens from Authorization Server Database πŸ—„οΈ

this threat applies if the authorization server stores access tokens as handles in a database. an attacker may get access tokens from that database by getting into the database or by launching a SQL injection attack. 😱

Impact: disclosure of all access tokens. 🚨

Countermeasures:

  • enforce system security measures (Section 5.1.4.1.1). πŸ›‘οΈ
  • store access token hashes only (Section 5.1.4.1.3). 🫢
  • enforce standard SQL injection countermeasures (Section 5.1.4.1.2). πŸ’…

4.3.3. Threat: Disclosure of Client Credentials during Transmission πŸ“‘

an attacker could try to eavesdrop on the transmission of client credentials between the client and server, either during the client authentication process or during OAuth token requests. πŸ‘€

Impact: revelation of a client credential, enabling phishing or impersonation of a client service. 🎭

Countermeasures:

  • the transmission of client credentials must be protected using transport-layer mechanisms such as TLS (see Section 5.1.1). πŸ”’
  • use alternative authentication means that don't require sending plaintext credentials over the wire (e.g., Hash-based Message Authentication Code). πŸ¦‹

4.3.4. Threat: Obtaining Client Secret from Authorization Server Database πŸ—οΈ

an attacker may get valid "client_id"/secret combinations from the authorization server's database, by getting into the database or by launching a SQL injection attack. 😭

Impact: disclosure of all "client_id"/secret combinations. this allows the attacker to act on behalf of legitimate clients. πŸ™ˆ

Countermeasures:

  • enforce system security measures (Section 5.1.4.1.1). πŸ›‘οΈ
  • enforce standard SQL injection countermeasures (Section 5.1.4.1.2). πŸ’…
  • ensure proper handling of credentials as per "Enforce Credential Storage Protection Best Practices" (Section 5.1.4.1). 🧚

4.3.5. Threat: Obtaining Client Secret by Online Guessing 🎯

an attacker may try to guess valid "client_id"/secret pairs. 🀨

Impact: disclosure of a single "client_id"/secret pair. πŸ₯²

Countermeasures:

  • use high entropy for secrets (Section 5.1.4.2.2). 🌈
  • lock accounts (Section 5.1.4.2.3). πŸ”
  • use strong client authentication (Section 5.2.3.7). πŸ‘‘

4.4. Obtaining Authorization ⭐

this section covers threats that are specific to certain flows used to obtain access tokens. 🧩 each flow is characterized by response types and/or grant types on the end-user authorization and token endpoint, respectively. πŸ’œ

4.4.1. Authorization "code" πŸŽ€

4.4.1.1. Threat: Eavesdropping or Leaking Authorization "codes" ✨

okay bestie, so an attacker could try to eavesdrop on the authorization "codes" while they're traveling between the authorization server and the client πŸ‘€. The messy part is that authorization "codes" get passed around through the browser, and that can leak them to untrusted websites and attackers in a few different ways πŸ™ˆ

  • Referrer headers πŸ’Œ: Browsers often send a referer header when a page embeds content, or when a user hops from one web page to another. These can get sent even when the origin site doesn't trust the destination site 😬. The referrer header is commonly logged for traffic analysis purposes.
  • Request logs πŸ“œ: Web server request logs commonly include query parameters on requests, so the codes can end up sitting in there.
  • Open redirectors πŸšͺ: Websites sometimes need to send users somewhere else through a redirector. Open redirectors are a particular risk for web-based delegation protocols because the redirector can leak verification codes to untrusted destination sites πŸ’€.
  • Browser history πŸ•°οΈ: Browsers commonly record visited URLs in the browser history. Another user of the same browser may be able to see URLs that previous users visited, which is giving "someone's been snooping" πŸ‘€.

Note: A description of similar attacks on the SAML protocol can be found at [OASIS.sstc-saml-bindings-1.1], Section 4.1.1.9.1; [Sec-Analysis]; and [OASIS.sstc-sec-analysis-response-01]. πŸ“š

Countermeasures: πŸ›‘οΈ

  • As per the core OAuth spec, the authorization server as well as the client must ensure that these transmissions are protected using transport-layer mechanisms such as TLS (see Section 5.1.1). Locking these down is non-negotiable, bestie πŸ”’
  • The authorization server will require the client to authenticate wherever possible, so the binding of the authorization "code" to a certain client can be validated in a reliable way (see Section 5.2.4.4). Main character energy for the client authentication check πŸ’…
  • Use short expiry time for authorization "codes" (Section 5.1.5.3). ⏳
  • The authorization server should enforce a one-time usage restriction (see Section 5.1.5.4). One and done, periodt 🫢
  • If an authorization server observes multiple attempts to redeem an authorization "code", the authorization server may want to revoke all tokens granted based on the authorization "code" (see Section 5.2.1.1). Multiple redeem attempts = red flag 🚩
  • In the absence of these countermeasures, reducing scope (Section 5.1.5.1) and expiry time (Section 5.1.5.3) for access tokens can be used to reduce the damage in case of leaks. Lowkey a backup plan, but a good one πŸŽ€
  • The client server may reload the target page of the redirect URI in order to automatically clean up the browser cache. 🧹

4.4.1.2. Threat: Obtaining Authorization "codes" from Authorization Server Database πŸ—„οΈ

This threat is applicable if the authorization server stores authorization "codes" as handles in a database. An attacker may obtain authorization "codes" from the authorization server's database by gaining access to the database or launching a SQL injection attack 😱

Impact: Disclosure of all authorization "codes", most likely along with the respective redirect_uri and client_id values. That's a whole vibe-ending situation πŸ’€

Countermeasures: πŸ›‘οΈ

  • Best practices for credential storage protection should be employed (Section 5.1.4.1).
  • Enforce system security measures (Section 5.1.4.1.1).
  • Store access token hashes only (Section 5.1.4.1.3). Hash it, don't store it raw πŸ”
  • Enforce standard SQL injection countermeasures (Section 5.1.4.1.2). No injection drama allowed πŸ™…β€β™€οΈ

4.4.1.3. Threat: Online Guessing of Authorization "codes" 🎲

An attacker may try to guess valid authorization "code" values and send the guessed code value using the grant type "code" in order to obtain a valid access token. Guessing game, but make it dangerous 😬

Impact: Disclosure of a single access token and probably also an associated refresh token.

Countermeasures: πŸ›‘οΈ

  • Handle-based tokens must use high entropy (Section 5.1.4.2.2). Make them random enough that guessing is basically impossible ✨
  • Assertion-based tokens should be signed (Section 5.1.5.9). πŸ–‹οΈ
  • Authenticate the client; this adds another value that the attacker has to guess (Section 5.2.3.4). Extra layer = extra iconic πŸ‘‘
  • Bind the authorization "code" to the redirect URI; this adds another value that the attacker has to guess (Section 5.2.4.5). 🎯
  • Use short expiry time for tokens (Section 5.1.5.3). ⏳

4.4.1.4. Threat: Malicious Client Obtains Authorization 😈

A malicious client could pretend to be a valid client and obtain an access authorization in this way. The malicious client could even use screen-scraping techniques to simulate a user's consent in the authorization flow. Not me sneaking in pretending to be the user πŸ™ˆ

Assumption: It is not the task of the authorization server to protect the end-user's device from malicious software. This is the responsibility of the platform running on the particular device, probably in cooperation with other components of the respective ecosystem (e.g., an application management infrastructure). The sole responsibility of the authorization server is to control access to the end-user's resources maintained in resource servers and to prevent unauthorized access to them via the OAuth protocol. Based on this assumption, the following countermeasures are available to cope with the threat. So the device itself is the platform's job, not the auth server's 🧚

Countermeasures: πŸ›‘οΈ

  • The authorization server should authenticate the client, if possible (see Section 5.2.3.4). Note: The authentication takes place after the end user has authorized the access. πŸ“
  • The authorization server should validate the client's redirect URI against the pre-registered redirect URI, if one exists (see Section 5.2.3.5). Note: An invalid redirect URI indicates an invalid client, whereas a valid redirect URI does not necessarily indicate a valid client. The level of confidence depends on the client type. For web applications, the level of confidence is high, since the redirect URI refers to the globally unique network endpoint of this application, whose fully qualified domain name (FQDN) is also validated using HTTPS server authentication by the user agent. In contrast, for native clients, the redirect URI typically refers to device local resources, e.g., a custom scheme. So, a malicious client on a particular device can use the valid redirect URI the legitimate client uses on all other devices. 🧐 Web apps are way easier to trust here, but native apps with custom schemes? Kinda sus 🫣
  • After authenticating the end user, the authorization server should ask him/her for consent. In this context, the authorization server should explain to the end user the purpose, scope, and duration of the authorization the client asked for. Moreover, the authorization server should show the user any identity information it has for that client. It is up to the user to validate the binding of this data to the particular application (e.g., Name) and to approve the authorization request (see Section 5.2.4.3). Read the consent screen, bestie πŸ‘€
  • The authorization server should not perform automatic re-authorizations for clients it is unable to reliably authenticate or validate (see Section 5.2.4.1). No auto-approving sketchy clients 🚫
  • If the authorization server automatically authenticates the end user, it may nevertheless require some user input in order to prevent screen scraping. Examples are CAPTCHAs (Completely Automated Public Turing tests to tell Computers and Humans Apart) or other multi-factor authentication techniques such as random questions, token code generators, etc. πŸ€– Prove you're human, babe
  • The authorization server may also limit the scope of tokens it issues to clients it cannot reliably authenticate (see Section 5.1.5.1). Less access for the mystery clients πŸŽ€

4.4.1.5. Threat: Authorization "code" Phishing 🎣

A hostile party could impersonate the client site and get access to the authorization "code". This could be achieved using DNS or ARP spoofing. This applies to clients which are web applications; thus, the redirect URI is not local to the host where the user's browser is running. Imposter behavior, and we are NOT here for it πŸ™…β€β™€οΈ

Impact: This affects web applications and may lead to a disclosure of authorization "codes" and, potentially, the corresponding access and refresh tokens.

Countermeasures:

It is strongly recommended that one of the following countermeasures be utilized in order to prevent this attack: πŸ”₯

  • The redirect URI of the client should point to an HTTPS-protected endpoint, and the browser should be utilized to authenticate this redirect URI using server authentication (see Section 5.1.2). πŸ”
  • The authorization server should require that the client be authenticated, i.e., confidential client, so the binding of the authorization "code" to a certain client can be validated in a reliable way (see Section 5.2.4.4). πŸ’–

4.4.1.6. Threat: User Session Impersonation 🎭

A hostile party could impersonate the client site and impersonate the user's session on this client. This could be achieved using DNS or ARP spoofing. This applies to clients which are web applications; thus, the redirect URI is not local to the host where the user's browser is running. Okay this one is giving full identity theft energy 😭

Impact: An attacker who intercepts the authorization "code" as it is sent by the browser to the callback endpoint can gain access to protected resources by submitting the authorization "code" to the client. The client will exchange the authorization "code" for an access token and use the access token to access protected resources for the benefit of the attacker, delivering protected resources to the attacker, or modifying protected resources as directed by the attacker. If OAuth is used by the client to delegate authentication to a social site (e.g., as in the implementation of a "Login" button on a third-party social network site), the attacker can use the intercepted authorization "code" to log into the client as the user. Yikes, that's a full account takeover πŸ’€

Note: Authenticating the client during authorization "code" exchange will not help to detect such an attack, as it is the legitimate client that obtains the tokens. Client auth won't save you here, sis πŸ™ƒ

Countermeasures:

  • In order to prevent an attacker from impersonating the end-user's session, the redirect URI of the client should point to an HTTPS protected endpoint, and the browser should be utilized to authenticate this redirect URI using server authentication (see Section 5.1.2). HTTPS on the redirect URI is the move πŸ”’βœ¨

4.4.1.7. Threat: Authorization "code" Leakage through Counterfeit Client ✨

okay bestie, this one is a whole heist πŸ•΅οΈβ€β™€οΈπŸ’…. The attacker wants a victim to log in, approve access to their resources, and then get that authorization "code" slipped into a client app that's tied to the attacker's account. So the victim's stuff ends up linked to the attacker's profile 😳

The attacker takes an existing client app and combines it with their own counterfeit client website. The trick is that the victim expects the app to ask for access to some resource server. The victim sees a totally normal request from an app they recognize and clicks approve πŸ™ˆ Then the attacker uses that approval to get into information the victim never knowingly signed off on. unhinged, but it's literally how it goes πŸ’€

Here's the flow:

  1. The attacker opens the client website (or app) and starts a data access request to a particular resource server. The client site then starts an authorization request to that resource server's authorization server. Instead of continuing the normal process, the attacker edits the end-user authorization URL the client built so it includes a redirect URI parameter pointing to a website the attacker controls.
  2. The attacker tricks another user (the victim) into opening that modified end-user authorization URI and approving access, for example through an email link or a blog link. How the attacker pulls this off is out of scope.
  3. After clicking the link, the victim is asked to authenticate and authorize the client site to have access.
  4. Once authorization is done, the authorization server redirects the user agent to the attacker's website instead of the original client website.
  5. The attacker grabs the authorization "code" from their website using means that are out of scope for this document.
  6. Next, the attacker builds a redirect URI to the target website (or app) based on the original authorization request's redirect URI and the newly obtained authorization "code", then sends their user agent to that URL. The authorization "code" gets injected into the original client site (or app).
  7. The client site uses the authorization "code" to fetch a token from the authorization server and links that token to the attacker's user account on the site.
  8. Now the attacker can get into the victim's resources through the client site 😈

Impact: The attacker gets access to the victim's resources, which are now associated with the attacker's account on the client site.

Countermeasures:

  • The attacker will need to use a different redirect URI for their authorization process rather than the target website, because they need to intercept the flow. So, if the authorization server associates the authorization "code" with the redirect URI of a particular end-user authorization and checks that redirect URI against the redirect URI passed to the token endpoint, this kind of attack gets caught (see Section 5.2.4.5).
  • The authorization server may also enforce the use and validation of pre-registered redirect URIs (see Section 5.2.3.5). This allows early recognition of authorization "code" disclosure to counterfeit clients πŸ”
  • For native applications, one could also consider using deployment-specific client ids and secrets (see Section 5.2.3.4), along with binding authorization "codes" to "client_ids" (see Section 5.2.4.4). This helps detect the attack, because the attacker does not have access to the deployment-specific secret. So the attacker won't be able to exchange the authorization "code" πŸ”
  • The client may consider using other flows that are not vulnerable to this kind of attack, such as the implicit grant type (see Section 4.4.2) or resource owner password credentials (see Section 4.4.3).

4.4.1.8. Threat: CSRF Attack against redirect-uri πŸŽ€

Cross-site request forgery (CSRF) is a web attack where HTTP requests get sent from a user that a website trusts or has authenticated (for example, through HTTP redirects or HTML forms). CSRF attacks on OAuth approvals can let an attacker get authorization to OAuth protected resources without the user's consent 😱

This attack goes after the redirect URI used in the authorization "code" flow. The attacker authorizes an authorization "code" for their own protected resources on an authorization server. Then they abort the redirect flow back to the client on their own device and trick the victim into following the redirect back to the client. The client receives the redirect, fetches the token(s) from the authorization server, and links the victim's client session to the resources the token can access.

Impact: The user ends up accessing resources on behalf of the attacker. How bad it gets depends on the type of resource accessed. For example, the user might upload private items to the attacker's resources. Or, when OAuth is used for 3rd-party login, the user might link their client account to the attacker's identity at the external Identity Provider. In that case, the attacker could easily access the victim's data at the client by logging in from another device with their own credentials at the external Identity Provider. Scary stuff πŸ₯²

Countermeasures:

  • The "state" parameter should be used to link the authorization request with the redirect URI used to deliver the access token (Section 5.3.5).
  • Client developers and end users can be educated not to follow untrusted URLs 🚫

4.4.1.9. Threat: Clickjacking Attack against Authorization πŸ–±οΈ

Clickjacking is when a malicious site loads the target site in a transparent iFrame (see [iFrame]) that sits on top of a set of dummy buttons. Those dummy buttons are carefully placed right under important buttons on the target site. So when a user clicks a button they can see, they're actually clicking a button (like an "Authorize" button) on the hidden page. Sneaky sneaky 🫣

Impact: An attacker can steal a user's authentication credentials and access their resources.

Countermeasures:

  • For newer browsers, avoiding iFrames during authorization can be enforced on the server side by using the X-FRAME-OPTIONS header (Section 5.2.2.6) ✨
  • For older browsers, JavaScript frame-busting (see [Framebusting]) techniques can be used, but they may not be effective in all browsers.

4.4.1.10. Threat: Resource Owner Impersonation πŸ‘‘

When a client asks for access to protected resources, the authorization flow normally includes the resource owner explicitly responding to the request, either granting or denying access. A malicious client can exploit knowledge of how this flow is structured to get authorization without the resource owner's consent. It does this by sending the necessary requests programmatically and simulating the flow against the authorization server. That way, the client can get into the victim's resources without their approval 😀 An authorization server is vulnerable to this threat if it uses non-interactive authentication mechanisms or splits the authorization flow across multiple pages.

The malicious client might embed a hidden HTML user agent, interpret the HTML forms sent by the authorization server, and automatically send the matching form HTTP POST requests. The attacker needs one prerequisite: they have to run the authorization process inside an already-authenticated session of the resource owner with the authorization server. There are a few ways to get there:

  • The malicious client could abuse an existing session in an external browser or cross-browser cookies on the particular device.
  • The malicious client could also request authorization for an initial scope that's acceptable to the user, then quietly abuse the resulting session in their browser instance to "silently" request another scope.
  • Alternatively, the attacker might exploit an authorization server's ability to authenticate the resource owner automatically and without user interaction, for example based on certificates.

In all cases, this attack is limited to clients running on the victim's device, either within the user agent or as a native app.

Please note: Such attacks cannot be prevented using CSRF countermeasures, since the attacker just "executes" the URLs as prepared by the authorization server, including any nonce, etc. πŸ™…β€β™€οΈ

Countermeasures:

Authorization servers should decide, based on an analysis of the risk associated with this threat, whether to detect and prevent it 🧠

To prevent this kind of attack, the authorization server may force a user interaction based on non-predictable input values as part of the user consent approval. The authorization server could:

  • combine password authentication and user consent in a single form,
  • make use of CAPTCHAs, or
  • use one-time secrets sent out of band to the resource owner (for example, via text or instant message).

Alternatively, to let the resource owner detect abuse, the authorization server could notify the resource owner of any approval by appropriate means, for example by text or instant message, or email πŸ“²


4.4.1.11. Threat: DoS Attacks That Exhaust Resources 🌊

If an authorization server includes a not-so-trivial amount of entropy in authorization "codes" or access tokens (which limits the number of possible codes/tokens), and automatically grants them without user intervention, and has no limit on codes or access tokens per user, an attacker could exhaust the pool of authorization "codes". They'd do this by repeatedly directing the user's browser to request authorization "codes" or access tokens. 😩

Countermeasures:

  • The authorization server should consider limiting the number of access tokens granted per user.
  • The authorization server should include a nontrivial amount of entropy in authorization "codes" πŸ’œ

4.4.1.12. Threat: DoS Using Manufactured Authorization "codes" πŸ’₯

okay so picture this: an attacker with a botnet πŸ€– finds the redirect URIs of clients that listen on HTTP, hits them with random authorization "codes", and suddenly a huge pile of HTTPS connections lands on the authorization server all at once. 😭 that's a denial-of-service (DoS) attack on the authorization server, and it's giving main character villain energy.

this still works even when the CSRF defense and the "state" parameter (see Section 4.4.1.8) are set up on the client side πŸ™ƒ with that defense, the attacker might have to make one extra HTTP request just to grab a valid CSRF code/"state" parameter. that apparently cuts the attack's effectiveness by a factor of 2. but if the HTTPS/HTTP cost ratio is higher than 2 (the cost factor is estimated to be around 3.5x at [SSL-Latency]), the attacker still gets a magnification of resource utilization at the authorization server's expense. so it's still a win for them, ngl πŸ’€

Impact: there are a few things the attacker can pull off with this OAuth flow that they can't easily do otherwise ✨

  1. Connection laundering: the clients act as the relay between the attacker and the authorization server, so the authorization server learns little or no information about who the attacker actually is πŸ•΅οΈβ€β™€οΈ rate-limiting the offending attacker machines gets way less effective because it's hard to figure out which machines are attacking. an attacker could also launder their connections through an anonymizing system like Tor, but how well that works depends on the capacity of that anonymizing system. on the other hand, a potentially large number of OAuth clients could be used for this attack 🌈
  2. Asymmetric resource utilization: the attacker pays for one HTTP connection and that causes an HTTPS connection to happen on the authorization server πŸ’… the attacker can coordinate the timing of those HTTPS connections across multiple clients pretty easily. they could get something similar by putting an iFrame that points to the HTTPS URL of the authorization server into an HTTP web page and luring web users to visit it. but timing attacks using that scheme may be harder, since it seems tricky to get a large number of users to visit a particular site under the attacker's control at the same time πŸ™ˆ

Countermeasures:

  • Not a complete fix on their own, but CSRF defense and a "state" parameter made with secure random codes should be deployed on the client side πŸ” the client should forward the authorization "code" to the authorization server only after both the CSRF token and the "state" parameter have been validated ✨
  • If the client authenticates the user, either through a single-sign-on protocol or through local authentication, the client should suspend access for a user account if the number of invalid authorization "codes" submitted by that user goes over a certain threshold 🚫
  • The authorization server should send an error response to the client reporting an invalid authorization "code", and rate-limit or disallow connections from clients whose number of invalid requests goes over a threshold πŸ›‘

4.4.1.13. Threat: Code Substitution (OAuth Login) 🎭

an attacker could try to log into an application or website as the victim 😀 apps that rely on identity data from an OAuth protected service API to log users in are vulnerable to this. you'll see this pattern in so-called "social login" setups.

here's the prerequisite: a resource server offers an API that returns personal information about a user, and that info could be read as proof of a user's identity. so the client is treating the resource server API like an "identity" API πŸ‘€ the client uses OAuth to get an access token for that identity API, then asks the identity API for an identifier and uses it to look up its own internal user account data (login). the client assumes that, because it could get info about the user, the user has been authenticated. πŸ€”

if the client uses the grant type "code", the attacker needs to collect a valid authorization "code" for the victim from the same Identity Provider the target client app uses 😈 the attacker tricks the victim into logging into a malicious app (which might look legit to the Identity Provider) through that same Identity Provider. this makes the Identity Provider's authorization server issue an authorization "code" for the identity API. the malicious app then sends this code to the attacker, which kicks off a login process inside the target application. the attacker then tampers with the authorization response and swaps in their own code (bound to their identity) for the victim's code πŸ”„ the client exchanges that code for an access token, and the identity API accepts it, since the audience is correct with respect to the resource server. but the identifier the identity API returns is determined by the identity in the access token (which was issued based on the victim's code), so the attacker gets logged into the target application as the victim 😱

Impact: the attacker gets into an application and gets to see user-specific data inside it πŸ—οΈ

Countermeasures:

  • All clients must indicate their client ids with every request to exchange an authorization "code" for an access token πŸͺͺ the authorization server must validate whether that particular authorization "code" was issued to that particular client. if possible, the client should be authenticated beforehand.
  • Clients should use an appropriate protocol, such as OpenID (cf. [OPENID]) or SAML (cf. [OASIS.sstc-saml-bindings-1.1]), to implement user login 🫢 both of them support audience restrictions on clients.

4.4.2. Implicit Grant 🌸

in the implicit grant type flow, the access token gets returned straight to the client as a fragment part of the redirect URI. the idea is that the token isn't sent to the redirect URI target, since HTTP user agents don't send the fragment part of URIs to HTTP servers ✨ so an attacker can't eavesdrop on the access token along that path, and the token can't leak through HTTP referrer headers. πŸ¦‹

4.4.2.1. Threat: Access Token Leak in Transport/Endpoints πŸ“‘

this token might get eavesdropped by an attacker πŸ‘‚ the token is sent from the server to the client through a URI fragment of the redirect URI. if the communication isn't secured, or the endpoint isn't secured, the token could be leaked by parsing the returned URI 😬

Impact: the attacker could take on the same rights granted by the token πŸ₯·

Countermeasures:

  • The authorization server should ensure confidentiality (e.g., using TLS) of the response from the authorization server to the client (see Section 5.1.1). πŸ”’

4.4.2.2. Threat: Access Token Leak in Browser History πŸ•°οΈ

an attacker could grab the token from the browser's history. note that this means the attacker needs access to the particular device πŸ“±

Countermeasures:

  • Use short expiry times for tokens (see Section 5.1.5.3). A reduced scope for the token may lower the impact of that attack (see Section 5.1.5.1). ⏳
  • Make responses non-cacheable. πŸ™…β€β™€οΈ

4.4.2.3. Threat: Malicious Client Obtains Authorization 🦹

a malicious client could try to get a token by fraud πŸƒ

The same countermeasures as for Section 4.4.1.4 are applicable, except client authentication.

4.4.2.4. Threat: Manipulation of Scripts 🧩

a hostile party could act as the client web server and replace or modify the actual implementation of the client (script). this could be done using DNS or ARP spoofing πŸ•ΈοΈ this applies to clients implemented inside the web browser in a scripting language.

Impact: the attacker could get user credential information and fully assume the user's identity 😭

Countermeasures:

  • The authorization server should authenticate the server that scripts are obtained from (see Section 5.1.2). πŸͺͺ
  • The client should make sure scripts it gets haven't been altered in transport (see Section 5.1.1). πŸ”
  • Introduce one-time, per-use secrets (e.g., "client_secret") values that can only be used by scripts in a small time window once they're loaded from a server πŸ“ the goal is to make copying client-side scripts for reuse in an attacker's modified code less effective.

4.4.2.5. Threat: CSRF Attack against redirect-uri 🎯

CSRF attacks (see Section 4.4.1.8) also work against the redirect URI used in the implicit grant flow πŸ™ƒ an attacker could get an access token for their own protected resources. they could then build a redirect URI and embed their access token in it. if they can trick the user into following that redirect URI, and the client doesn't have protection against this attack, the user may end up with the attacker's access token authorized inside their client 😳

Impact: the user accesses resources on the attacker's behalf 🫠 the real effect depends on the type of resource accessed. for example, the user might upload private items to the attacker's resources. or, when OAuth is used in 3rd-party login scenarios, the user may link their client account to the attacker's identity at the external Identity Provider. that way, the attacker could easily access the victim's data at the client by logging in from another device with their credentials at the external Identity Provider πŸ₯€

Countermeasures:

  • The "state" parameter should be used to link the authorization request with the redirect URI used to deliver the access token. this makes sure the client won't be tricked into completing any redirect callback unless it's linked to an authorization request the client started itself πŸ”— the "state" parameter should not be guessable, and the client should be able to keep the "state" parameter secret 🀫
  • Client developers and end users can be educated not to follow untrusted URLs. πŸš«πŸ”—

4.4.2.6. Threat: Token Substitution (OAuth Login) 🎭

okay so bestie, picture this: an attacker wants to log into an app as YOU 😭 Apps that use identity data from an OAuth-protected API to log users in are open to this one. It shows up a lot in so-called "social login" setups, so ngl it's super relevant 🫢

For this to work, a resource server has to offer an API that returns personal info about a user, and the client treats that API as an "identity" API πŸ‘€ The client uses OAuth to get an access token for it, asks the identity API for an identifier, and uses that to look up its own internal user account (aka login). The client assumes that because it could get info about the user, the user must be authenticated. πŸ’…

Now the attacker needs a valid access token from the same Identity Provider the target app uses, and they need the victim's. They trick the victim into logging into a malicious app (which might look totally legit to the Identity Provider) using that same Identity Provider πŸ™ˆ The Identity Provider's authorization server then issues an access token for the identity API. The malicious app sends that token to the attacker, which kicks off a login inside the target app. Then the attacker swaps their own access token (tied to their identity) in place of the victim's 😈 The identity API accepts it because the audience, with respect to the resource server, is correct. And since the identifier coming back is based on the identity inside the access token, the attacker ends up logged into the target app as the victim. literally iconic villain arc ✨

Impact: The attacker gets into an application and gets their hands on user-specific data inside it. πŸ’€

Countermeasures:

  • Clients should use an appropriate protocol, such as OpenID (cf. [OPENID]) or SAML (cf. [OASIS.sstc-saml-bindings-1.1]) to implement user login. Both support audience restrictions on clients. πŸ”’

4.4.3. Resource Owner Password Credentials πŸ—οΈ

ok so the resource owner password credentials grant type (see [RFC6749], Section 4.3) is often kept around for legacy and migration reasons πŸ•°οΈ It lets a client grab an access token using an end-user's user id and password, plus its own credential. This grant type is riskier because it keeps the UID/password anti-pattern alive 😬 Also, since the user has zero control over the authorization process, clients using it aren't limited by scope and could potentially have the same capabilities as the user themselves πŸ’€ And since there's no authorization step, token revocation can't really be offered. bypassed, bestie πŸ™ƒ

Passwords get reused across like, a million services, so this anti-pattern can put whatever else is reachable with the same credential at risk 🚨 Even easy variations (think joe@example.com and joe@example.net) can make it way too easy for someone to guess that the same password works somewhere else πŸ‘€

Impact: The resource server can only tell scopes apart based on which client the access token is tied to. The client could also grab long-lived tokens and hand them over to an attacker's web service for more abuse 😱 The client, eavesdroppers, or endpoints could all snoop the user id and password.

Countermeasures:

  • Except for migration reasons, minimize use of this grant type. 🧹
  • The authorization server should validate the client id associated with the particular refresh token with every refresh request (Section 5.2.2.2).
  • As per the core OAuth specification, the authorization server must ensure that these transmissions are protected using transport-layer mechanisms such as TLS (see Section 5.1.1). πŸ”
  • Rather than encouraging users to use a UID and password, service providers should instead encourage users not to use the same password for multiple services. πŸ™Œ
  • Limit use of resource owner password credential grants to scenarios where the client application and the authorizing service are from the same organization. 🏒

4.4.3.1. Threat: Accidental Exposure of Passwords at Client Site 🫣

if the client doesn't protect things well enough, an attacker or a disgruntled employee could grab a user's passwords 😀

Countermeasures:

  • Use other flows that do not rely on the client's cooperation for secure resource owner credential handling. πŸ™…β€β™€οΈ
  • Use digest authentication instead of plaintext credential processing.
  • Obfuscate passwords in logs. πŸ«₯

4.4.3.2. Threat: Client Obtains Scopes without End-User Authorization 🎟️

all the interaction with the resource owner is done by the client, soooo it might (on purpose or by accident) end up with a token that has scope the resource owner didn't know about or didn't intend 😳 For example, the resource owner thinks the client only needs and gets read-only access to their media storage, but the client goes for a token with full access permissions. nah 🚫

Countermeasures:

  • Use other flows that do not rely on the client's cooperation for resource owner interaction. πŸ™…β€β™€οΈ
  • The authorization server may generally restrict the scope of access tokens (Section 5.1.5.1) issued by this flow. If the particular client is trustworthy and can be authenticated in a reliable way, the authorization server could relax that restriction. Resource owners may prescribe (e.g., in their preferences) what the maximum scope is for clients using this flow. βš–οΈ
  • The authorization server could notify the resource owner by an appropriate medium, e.g., email, of the grant issued (see Section 5.1.3). πŸ“§

4.4.3.3. Threat: Client Obtains Refresh Token through Automatic Authorization πŸ€–

same energy as before: the client handles all the resource owner interaction, so it might (intentionally or not) end up with long-term authorization in the form of a refresh token even though the resource owner never meant to give that 😭

Countermeasures:

  • Use other flows that do not rely on the client's cooperation for resource owner interaction. πŸ™…β€β™€οΈ
  • The authorization server may generally refuse to issue refresh tokens in this flow (see Section 5.2.2.1). If the particular client is trustworthy and can be authenticated in a reliable way (see client authentication), the authorization server could relax that restriction. Resource owners may allow or deny (e.g., in their preferences) the issuing of refresh tokens using this flow as well. πŸ›‘
  • The authorization server could notify the resource owner by an appropriate medium, e.g., email, of the refresh token issued (see Section 5.1.3). πŸ“¬

4.4.3.4. Threat: Obtaining User Passwords on Transport πŸ“‘

an attacker could try to eavesdrop on end-user credentials sent with the grant type "password" between the client and the server πŸ‘‚

Impact: Disclosure of a single end-user's password. πŸ’”

Countermeasures:

  • Ensure confidentiality of requests (Section 5.1.1). πŸ”
  • Use alternative authentication means that do not require the sending of plaintext credentials over the wire (e.g., Hash-based Message Authentication Code). ✨

4.4.3.5. Threat: Obtaining User Passwords from Authorization Server Database πŸ—„οΈ

an attacker may get valid username/password combos from the authorization server's database, either by getting into the database or by launching a SQL injection attack πŸ’‰

Impact: Disclosure of all username/password combinations. The impact may exceed the domain of the authorization server, since many users tend to use the same credentials on different services. 😱

Countermeasures:

  • Enforce credential storage protection best practices (Section 5.1.4.1). πŸ›‘οΈ

4.4.3.6. Threat: Online Guessing 🎲

an attacker may try to guess valid username/password combinations using the grant type "password" 🀞

Impact: Revelation of a single username/password combination.

Countermeasures:

  • Utilize secure password policy (Section 5.1.4.2.1). πŸ”€
  • Lock accounts (Section 5.1.4.2.3). πŸ”’
  • Use tar pit (Section 5.1.4.2.4). πŸ•³οΈ
  • Use CAPTCHAs (Section 5.1.4.2.5). πŸ€–
  • Consider not using the grant type "password". πŸ™
  • Client authentication (see Section 5.2.3) will provide another authentication factor and thus hinder the attack. 🧱

4.4.4. Client Credentials πŸͺͺ

client credentials (see [RFC6749], Section 3) are made of an identifier (which isn't secret) plus an additional means of authenticating a client, like a matching client secret 🀫 The threats to this grant type are pretty similar to the ones in Section 4.4.3, so keep those in mind πŸ’–


4.5. Refreshing an Access Token πŸ”„

4.5.1. Threat: Eavesdropping Refresh Tokens from Authorization Server πŸ‘€

an attacker may eavesdrop on refresh tokens while they're being sent from the authorization server to the client πŸ“¨

Countermeasures:

  • As per the core OAuth spec, the authorization servers must ensure that these transmissions are protected using transport-layer mechanisms such as TLS (see Section 5.1.1). πŸ”
  • If end-to-end confidentiality cannot be guaranteed, reducing scope (see Section 5.1.5.1) and expiry time (see Section 5.1.5.3) for issued access tokens can be used to reduce the damage in case of leaks. ⏳

4.5.2. Threat: Obtaining Refresh Token from Authorization Server Database πŸ—ƒοΈ

this threat applies if the authorization server stores refresh tokens as handles in a database. An attacker may grab refresh tokens from that database, either by getting into it or by launching a SQL injection attack πŸ’‰

Impact: Disclosure of all refresh tokens. 😭

Countermeasures:

  • Enforce credential storage protection best practices (Section 5.1.4.1). πŸ›‘οΈ
  • Bind token to client id, if the attacker cannot obtain the required id and secret (Section 5.1.5.8). 🧷

4.5.3. Threat: Obtaining Refresh Token by Online Guessing 🎯

an attacker may try to guess valid refresh token values and send them using the grant type "refresh_token" to get a valid access token 🫣

Impact: Exposure of a single refresh token and derivable access tokens.

Countermeasures:

  • For handle-based designs (Section 5.1.4.2.2). πŸ”–
  • For assertion-based designs (Section 5.1.5.9). πŸ“œ
  • Bind token to client id, because the attacker would guess the matching client id, too (see Section 5.1.5.8). πŸ”—
  • Authenticate the client; this adds another element that the attacker has to guess (see Section 5.2.3.4). 🧠

4.5.4. Threat: Refresh Token Phishing by Counterfeit Authorization Server 🎣

an attacker could try to get valid refresh tokens by proxying requests to the authorization server πŸ‘» If the authorization server URL is well-known at development time, or can at least be obtained from a well-known resource server, the attacker must use some kind of spoofing to pull this off.

Countermeasures:

  • Utilize server authentication (as described in Section 5.1.2). πŸͺͺ

4.6. Accessing Protected Resources 🌟

4.6.1. Threat: Eavesdropping Access Tokens on Transport πŸ‘€

okay so picture this: an attacker is sneaking around trying to snag a valid access token while it's zooming between the client and the resource server 😭. Access tokens are shared secrets between the authorization server and resource server, so they should be treated with the same care as other credentials (e.g., end-user passwords) πŸ”.

Countermeasures:

  • Access tokens sent as bearer tokens should not be sent in the clear over an insecure channel. As per the core OAuth spec, transmission of access tokens must be protected using transport-layer mechanisms such as TLS (see Section 5.1.1) πŸ›‘οΈ.
  • A short lifetime reduces impact in case tokens are compromised (see Section 5.1.5.3) ⏳.
  • The access token can be bound to a client's identifier and require the client to prove legitimate ownership of the token to the resource server (see Section 5.4.2) πŸ’….

4.6.2. Threat: Replay of Authorized Resource Server Requests πŸ”

an attacker could try replaying valid requests to grab or mess with user data, which is giving chaotic villain energy πŸ’€.

Countermeasures:

  • The resource server should utilize transport security measures (e.g., TLS) in order to prevent such attacks (see Section 5.1.1). This would prevent the attacker from capturing valid requests πŸ”’.
  • Alternatively, the resource server could employ signed requests (see Section 5.4.3) along with nonces and timestamps in order to uniquely identify requests. The resource server should detect and refuse every replayed request πŸ™…β€β™€οΈβœ¨.

4.6.3. Threat: Guessing Access Tokens 🎲

where the token is a handle, the attacker may try to guess access token values based on what they know from other access tokens. Not me trying to guess someone's password πŸ™ˆ.

Impact: Access to a single user's data.

Countermeasures:

  • Handle tokens should have a reasonable level of entropy (see Section 5.1.4.2.2) in order to make guessing a valid token value infeasible 🧠.
  • Assertion (or self-contained token) token contents should be protected by a digital signature (see Section 5.1.5.9) ✍️.
  • Security can be further strengthened by using a short access token duration (see Sections 5.1.5.2 and 5.1.5.3) πŸ’–.

4.6.4. Threat: Access Token Phishing by Counterfeit Resource Server 🎣

an attacker may pretend to be a particular resource server and to accept tokens from a particular authorization server. If the client sends a valid access token to this counterfeit resource server, the server in turn may use that token to access other services on behalf of the resource owner. This is the catfish of token theft 😭🐟.

Countermeasures:

  • Clients should not make authenticated requests with an access token to unfamiliar resource servers, regardless of the presence of a secure channel. If the resource server URL is well-known to the client, it may authenticate the resource servers (see Section 5.1.2) 🧐.
  • Associate the endpoint URL of the resource server the client talked to with the access token (e.g., in an audience field) and validate the association at a legitimate resource server. The endpoint URL validation policy may be strict (exact match) or more relaxed (e.g., same host). This would require telling the authorization server about the resource server endpoint URL in the authorization process πŸ—ΊοΈ.
  • Associate an access token with a client and authenticate the client with resource server requests (typically via a signature, in order to not disclose a secret to a potential attacker). This prevents the attack because the counterfeit server is assumed to lack the capability to correctly authenticate on behalf of the legitimate client to the resource server (Section 5.4.2) πŸ”‘.
  • Restrict the token scope (see Section 5.1.5.1) and/or limit the token to a certain resource server (Section 5.1.5.5) 🚧.

4.6.5. Threat: Abuse of Token by Legitimate Resource Server or Client πŸ™ƒ

a legitimate resource server could try to use an access token to access another resource server. Similarly, a client could try to use a token obtained for one server on another resource server. Borrowing your bestie's login without asking is not it πŸ™…β€β™€οΈ.

Countermeasures:

  • Tokens should be restricted to particular resource servers (see Section 5.1.5.5) πŸŽ€.

4.6.6. Threat: Leak of Confidential Data in HTTP Proxies 🌐

an OAuth HTTP authentication scheme as discussed in [RFC6749] is optional. However, [RFC2616] relies on the Authorization and WWW-Authenticate headers to distinguish authenticated content so that it can be protected. Proxies and caches, in particular, may fail to adequately protect requests not using these headers. For example, private authenticated content may be stored in (and thus be retrievable from) publicly accessible caches. Your private stuff ending up on a public cache is literally the worst plot twist πŸ˜­πŸ“¦.

Countermeasures:

  • Clients and resource servers not using an OAuth HTTP authentication scheme (see Section 5.4.1) should take care to use Cache-Control headers to minimize the risk that authenticated content is not protected. Such clients should send a Cache-Control header containing the "no-store" option [RFC2616]. Resource server success (2XX status) responses to these requests should contain a Cache-Control header with the "private" option [RFC2616] 🧁.
  • Reducing scope (see Section 5.1.5.1) and expiry time (Section 5.1.5.3) for access tokens can be used to reduce the damage in case of leaks πŸ“‰.

4.6.7. Threat: Token Leakage via Log Files and HTTP Referrers πŸͺ΅

if access tokens are sent via URI query parameters, such tokens may leak to log files and the HTTP "referer". Tokens in the URL are just vibes waiting to get screenshotted πŸ“Έ.

Countermeasures:

  • Use Authorization headers or POST parameters instead of URI request parameters (see Section 5.4.1) πŸ’Œ.
  • Set logging configuration appropriately πŸ“.
  • Prevent unauthorized persons from access to system log files (see Section 5.1.4.1.1) πŸšͺ.
  • Abuse of leaked access tokens can be prevented by enforcing authenticated requests (see Section 5.4.2) πŸ”.
  • The impact of token leakage may be reduced by limiting scope (see Section 5.1.5.1) and duration (see Section 5.1.5.3) and by enforcing one-time token usage (see Section 5.1.5.4) ✨.

5. Security Considerations πŸ›‘οΈ

this section describes the countermeasures as recommended to mitigate the threats described in Section 4. This is the part where we get serious, bestie, so pay attention 🫢.

5.1. General

this section covers considerations that apply generally across all OAuth components (client, resource server, token server, and user agents) 🌸.

5.1.1. Ensure Confidentiality of Requests πŸ”’

this is applicable to all requests sent from the client to the authorization server or resource server. While OAuth provides a mechanism for verifying the integrity of requests, it provides no guarantee of request confidentiality. Unless further precautions are taken, eavesdroppers will have full access to request content and may be able to mount interception or replay attacks by using the contents of requests, e.g., secrets or tokens. Full access to request content is not the vibe 😱.

Attacks can be mitigated by using transport-layer mechanisms such as TLS [RFC5246]. A virtual private network (VPN), e.g., based on IPsec VPNs [RFC4301], may be considered as well 🧚.

Note: This document assumes end-to-end TLS protected connections between the respective protocol entities. Deployments deviating from this assumption by offloading TLS in between (e.g., on the data center edge) must refine this threat model in order to account for the additional (mainly insider) threat this may cause πŸ‘€.

This is a countermeasure against the following threats:

  • Replay of access tokens obtained on the token's endpoint or the resource server's endpoint
  • Replay of refresh tokens obtained on the token's endpoint
  • Replay of authorization "codes" obtained on the token's endpoint (redirect?)
  • Replay of user passwords and client secrets

5.1.2. Utilize Server Authentication πŸͺͺ

HTTPS server authentication or similar means can be used to authenticate the identity of a server. The goal is to reliably bind the fully qualified domain name of the server to the public key presented by the server during connection establishment (see [RFC2818]) πŸ”—.

The client should validate the binding of the server to its domain name. If the server fails to prove that binding, the communication is considered a man-in-the-middle attack 🚨. This security measure depends on the certification authorities the client trusts for that purpose. Clients should carefully select those trusted CAs and protect the storage for trusted CA certificates from modifications 🏰.

This is a countermeasure against the following threats:

  • Spoofing
  • Proxying
  • Phishing by counterfeit servers

5.1.3. Always Keep the Resource Owner Informed πŸ“£

transparency to the resource owner is a key element of the OAuth protocol. The user should always be in control of the authorization processes and get the necessary information to make informed decisions. Moreover, user involvement is a further security countermeasure. The user can probably recognize certain kinds of attacks better than the authorization server. Information can be presented or exchanged during the authorization process, after the authorization process, and every time the user wishes to get informed by using techniques such as:

  • User consent forms.
  • Notification messages (e.g., email, SMS, ...). Note that notifications can be a phishing vector. Messages should be such that look-alike phishing messages cannot be derived from them πŸ“±.
  • Activity/event logs.
  • User self-care applications or portals.

5.1.4. Credentials πŸ—οΈ

this section describes countermeasures used to protect all kinds of credentials from unauthorized access and abuse. Credentials are long-term secrets, such as client secrets and user passwords as well as all kinds of tokens (refresh and access tokens) or authorization "codes" πŸ’Ž.

5.1.4.1. Enforce Credential Storage Protection Best Practices 🏦

administrators should undertake industry best practices to protect the storage of credentials (for example, see [OWASP]). Such practices may include but are not limited to the following sub-sections πŸ“š.

5.1.4.1.1. Enforce Standard System Security Means πŸ”

a server system may be locked down so that no attacker may get access to sensitive configuration files and databases. Lock it down like your diary πŸ“”.

5.1.4.1.2. Enforce Standard SQL Injection Countermeasures πŸ’‰

if a client identifier or other authentication component is queried or compared against a SQL database, it may become possible for an injection attack to occur if parameters received are not validated before submission to the database. Nobody wants a drop table moment πŸ’€.

  • Ensure that server code is using the minimum database privileges possible to reduce the "surface" of possible attacks.
  • Avoid dynamic SQL using concatenated input. If possible, use static SQL.
  • When using dynamic SQL, parameterize queries using bind arguments. Bind arguments eliminate the possibility of SQL injections πŸ™Œ.
  • Filter and sanitize the input. For example, if an identifier has a known format, ensure that the supplied value matches the identifier syntax rules 🧼.

5.1.4.1.3. No Cleartext Storage of Credentials ✨

okay bestie, the authorization server should not store credentials in clear text πŸ™…β€β™€οΈ. The usual moves are to store hashes instead or to encrypt the credentials πŸ”. If the credential doesn't have a reasonable entropy level (aka it's a user password πŸ‘€), an additional salt will harden the storage so offline dictionary attacks are harder to pull off πŸ§‚.

Note: some authentication protocols need the authorization server to have access to the secret in the clear 🫣. Those protocols can't be implemented if the server only has access to hashes, so credentials should be strongly encrypted in those cases πŸ’œ.

5.1.4.1.4. Encryption of Credentials πŸ”’

ngl, insecurely saved client credentials are literally free snacks for attackers 🍭. Store client credentials using an encrypted persistence mechanism such as a keystore or database πŸ—οΈ. Also, compiling client credentials directly into client code makes client applications vulnerable to scanning πŸ”, and it's a pain to administer if the client credentials change over time 😀.

5.1.4.1.5. Use of Asymmetric Cryptography πŸ¦‹

Using asymmetric cryptography frees the authorization server from the obligation to manage credentials 🫢.

5.1.4.2. Online Attacks on Secrets 🎯

5.1.4.2.1. Utilize Secure Password Policy πŸ”

The authorization server may decide to enforce a complex user password policy to increase the entropy of user passwords, which helps hinder online password attacks πŸ›‘οΈ. Note that too much complexity can increase the likelihood that users re-use passwords πŸ™ˆ, write them down πŸ“, or otherwise store them insecurely πŸ’€.

5.1.4.2.2. Use High Entropy for Secrets ✨

When creating secrets not intended for usage by human users (e.g., client secrets or token handles), the authorization server should include a reasonable level of entropy to mitigate the risk of guessing attacks 🎲. The token value should be >=128 bits long and constructed from a cryptographically strong random or pseudo-random number sequence (see [RFC4086] for best current practice) generated by the authorization server πŸ’….

5.1.4.2.3. Lock Accounts πŸ”’

Online attacks on passwords can be mitigated by locking the respective accounts after a certain number of failed attempts πŸ™…β€β™€οΈ.

Note: this measure can be abused to lock down legitimate service users 😭.

5.1.4.2.4. Use Tar Pit 🐒

The authorization server may react to failed attempts to authenticate by username/password by temporarily locking the respective account and delaying the response for a certain duration ⏳. This duration may increase with the number of failed attempts. The whole point is to slow the attacker's attempts on a certain username down 🧊.

Note: this may require a more complex and stateful design of the authorization server 🧠.

5.1.4.2.5. Use CAPTCHAs πŸ€–

The idea is to prevent programs from automatically checking a huge number of passwords by requiring human interaction πŸ™‹β€β™€οΈ.

Note: this has a negative impact on user experience πŸ₯².

5.1.5. Tokens (Access, Refresh, Code) πŸŽ€

5.1.5.1. Limit Token Scope 🌸

The authorization server may decide to reduce or limit the scope associated with a token πŸ’œ. The basis of this decision is out of scope, but examples are:

  • a client-specific policy, e.g., issue only less powerful tokens to public clients,
  • a service-specific policy, e.g., it is a very sensitive service,
  • a resource-owner-specific setting, or
  • combinations of such policies and preferences.

The authorization server may allow different scopes depending on the grant type. For example, end-user authorization via direct interaction with the end user (authorization "code") might be considered more reliable than direct authorization via grant type "username"/"password" πŸ‘€. This means will reduce the impact of the following threats:

  • token leakage
  • token issuance to malicious software
  • unintended issuance of powerful tokens with resource owner credentials flow

5.1.5.2. Determine Expiration Time ⏰

Tokens should generally expire after a reasonable duration πŸ•°οΈ. This complements and strengthens other security measures (such as signatures) and reduces the impact of all kinds of token leaks 🫣. Depending on the risk associated with token leakage, tokens may expire after a few minutes (e.g., for payment transactions) or stay valid for hours (e.g., read access to contacts) πŸ“‡.

The expiration time is determined by several factors, including:

  • risk associated with token leakage,
  • duration of the underlying access grant,
  • duration until the modification of an access grant should take effect, and
  • time required for an attacker to guess or produce a valid token.

5.1.5.3. Use Short Expiration Time ⚑

A short expiration time for tokens is a means of protection against the following threats:

  • replay
  • token leak (a short expiration time will reduce impact)
  • online guessing (a short expiration time will reduce the likelihood of success)

Note: short token duration requires more precise clock synchronization between the authorization server and resource server ⏱️. Furthermore, shorter duration may require more token refreshes (access token) or repeated end-user authorization processes (authorization "code" and refresh token) πŸ”.

5.1.5.4. Limit Number of Usages or One-Time Usage 1️⃣

The authorization server may restrict the number of requests or operations that can be performed with a certain token 🚫. This mechanism can be used to mitigate the following threats:

  • replay of tokens
  • guessing

For example, if an authorization server observes more than one attempt to redeem an authorization "code", the authorization server may want to revoke all access tokens granted based on the authorization "code" as well as reject the current request 🚨.

As with the authorization "code", access tokens may also have a limited number of operations. This either forces client applications to re-authenticate and use a refresh token to obtain a fresh access token, or forces the client to re-authorize the access token by involving the user πŸ™‹β€β™€οΈ.

5.1.5.5. Bind Tokens to a Particular Resource Server (Audience) 🎯

Authorization servers in multi-service environments may consider issuing tokens with different content to different resource servers, and explicitly indicate in the token the target server the token is intended to be sent to 🫢. SAML assertions (see [OASIS.saml-core-2.0-os]) use the Audience element for this purpose πŸ’…. This countermeasure can be used in the following situations:

  • It reduces the impact of a successful replay attempt, since the token is applicable to a single resource server only.
  • It prevents abuse of a token by a rogue resource server or client, since the token can only be used on that server. It is rejected by other servers.
  • It reduces the impact of leakage of a valid token to a counterfeit resource server.

5.1.5.6. Use Endpoint Address as Token Audience πŸ“

This may be used to indicate to a resource server which endpoint URL has been used to obtain the token πŸ”Ž. This measure will allow the detection of requests from a counterfeit resource server, since such a token will contain the endpoint URL of that server πŸ•΅οΈβ€β™€οΈ.

5.1.5.7. Use Explicitly Defined Scopes for Audience and Tokens 🧚

Deployments may consider only using tokens with explicitly defined scopes, where every scope is associated with a particular resource server πŸ’–. This approach can be used to mitigate attacks where a resource server or client uses a token for a different purpose than the one intended πŸ™…β€β™€οΈ.

5.1.5.8. Bind Token to Client id πŸ”—

An authorization server may bind a token to a certain client identifier πŸͺͺ. This identifier should be validated for every request with that token. This technique can be used to:

  • detect token leakage and
  • prevent token abuse.

Note: validating the client identifier may require the target server to authenticate the client's identifier πŸ›‚. This authentication can be based on secrets managed independently of the token (e.g., pre-registered client id/secret on authorization server) or sent with the token itself (e.g., as part of the encrypted token content) πŸ”.

5.1.5.9. Sign Self-Contained Tokens ✍️

Self-contained tokens should be signed in order to detect any attempt to modify or produce faked tokens (e.g., Hash-based Message Authentication Code or digital signatures) πŸ•΅οΈ.

5.1.5.10. Encrypt Token Content πŸ”

Self-contained tokens may be encrypted for confidentiality reasons or to protect system internal data 🀫. Depending on the token format, keys (e.g., symmetric keys) may have to be distributed between server nodes πŸ—οΈ. The method of distribution should be defined by the token and the encryption used πŸ“œ.

5.1.5.11. Adopt a Standard Assertion Format πŸ†

For service providers intending to implement an assertion-based token design, it is highly recommended to adopt a standard assertion format (such as SAML [OASIS.saml-core-2.0-os] or the JavaScript Object Notation Web Token (JWT) [OAuth-JWT]) πŸ‘‘.

5.1.6. Access Tokens 🌈

The following measures should be used to protect access tokens πŸ’œ:

  • Keep them in transient memory (accessible by the client application only).
  • Pass tokens securely using secure transport (TLS).
  • Ensure that client applications do not share tokens with 3rd parties.

5.2. Authorization Server 🏰

This section describes considerations related to the OAuth authorization server endpoint πŸŽ€.

5.2.1. Authorization "codes" 🎟️

5.2.1.1. Automatic Revocation of Derived Tokens If Abuse Is Detected 🚨

If an authorization server observes multiple attempts to redeem an authorization grant (e.g., such as an authorization "code"), the authorization server may want to revoke all tokens granted based on the authorization grant πŸ’….

5.2.2. Refresh Tokens πŸ”„

5.2.2.1. Restricted Issuance of Refresh Tokens πŸ™…β€β™€οΈ

The authorization server may decide, based on an appropriate policy, not to issue refresh tokens. Since refresh tokens are long-term credentials, they may be subject to theft πŸ₯Ί. For example, if the authorization server does not trust a client to securely store such tokens, it may refuse to issue such a client a refresh token 🫣.

5.2.2.2. Binding of Refresh Token to "client_id" πŸ”—

The authorization server should match every refresh token to the identifier of the client to whom it was issued. The authorization server should check that the same client_id is present for every request to refresh the access token. If possible (e.g., confidential clients), the authorization server should authenticate the respective client πŸ›‘οΈ.

This is a countermeasure against refresh token theft or leakage πŸ’–.

Note: this binding should be protected from unauthorized modifications πŸ”’.

5.2.2.3. Refresh Token Rotation ✨

okay so refresh token rotation is basically the bodyguard for your refresh tokens πŸ’… its whole job is to automatically catch when someone tries to use the same refresh token in parallel from different apps or devices. this usually happens when a token gets stolen off the client and then both the attacker AND the legit client try to use it 😭 the big idea is to change the refresh token value with every single refresh request, so the server can spot anyone trying to get access tokens with an old refresh token πŸ•΅οΈβ€β™€οΈ the server can't tell if it's the attacker or the real client knocking, so when that happens, the valid refresh token AND the access authorization tied to it both get revoked. bestie that's a full lockdown πŸ”’

the OAuth spec supports this, because the token response lets the authorization server hand back a new refresh token even for requests with grant type refresh_token 🫢

Note: this can cause problems in clustered environments, since the currently valid refresh token has to be used for sure. in a setup like that, other measures might be more appropriate πŸ™ˆ

5.2.2.4. Revocation of Refresh Tokens 🧹

the authorization server may let clients or end users explicitly ask for refresh tokens to be invalidated πŸ™Œ there's a mechanism for revoking tokens specified in [OAuth-REVOCATION], so go check that out too.

this is a countermeasure against:

  • device theft,
  • impersonation of a resource owner, or
  • suspected compromised client applications.

5.2.2.5. Device Identification πŸ“±

the authorization server may require that authentication credentials get bound to a device identifier. the International Mobile Station Equipment Identity [IMEI] is one example of an identifier like this, and there are also operating system-specific identifiers 🧚 the server could include such an identifier when it authenticates user credentials, so it can detect token theft from a particular device.

Note: any implementation should think about the privacy implications of using device identifiers. this part matters, bestie 🫢

5.2.2.6. X-FRAME-OPTIONS Header πŸ–ΌοΈ

for newer browsers, you can enforce avoiding iFrames on the server side with the X-FRAME-OPTIONS header (see [X-Frame-Options]) πŸ’– it can have two values: DENY blocks any framing at all, and SAMEORIGIN blocks framing by sites with a different origin. the value ALLOW-FROM lists trusted origins that iFrames are allowed to come from ✨

this is a countermeasure against the following threat:

  • Clickjacking attacks

5.2.3. Client Authentication and Authorization πŸͺͺ

as Section 3 (Security Features) describes, clients get identified, authenticated, and authorized for several purposes, like:

  • collating requests to the same client,
  • showing the user that the client is recognized by the authorization server,
  • authorizing clients to access certain features on the authorization server or resource server, and
  • logging a client identifier into log files for analysis or statistics.

different client types have different capabilities and characteristics, so there are different ways to hit these goals, and we're gonna walk through them in this section 🌈 authorization server providers should be aware of the security policy and deployment of a particular client and adapt how they treat it. for example, one approach could be to treat all clients as less trustworthy and unsecure 😬 on the other extreme, a service provider could have an admin activate every client installation individually, and that way they gain confidence in the identity of the software package and the security of the environment it's installed in. there are several approaches in between too πŸ’…

5.2.3.1. Don't Issue Secrets to Clients with Inappropriate Security Policy 🚫🀫

authorization servers should not issue secrets to clients that cannot protect secrets ("public" clients) 😀 that cuts down the chance of the server treating the client as strongly authenticated.

for example, a single client id and secret shared by every installation of a native application is kinda pointless πŸ™ƒ that secret would have to get passed from the developer through the distribution channel, like an application market, to every installation on end-user devices. and a secret burned into the source code of the application or an associated resource bundle isn't protected from reverse engineering πŸ’€ secondly, those secrets can't be revoked, because that would instantly break every single installation. plus, since the authorization server can't really trust the client's identifier, it would be dangerous to show end users how trustworthy the client is.

there are other ways to get a reasonable security level, and we'll cover them in the following sections πŸ¦‹

authorization servers should not allow automatic authorization for public clients. the authorization server may issue an individual client id, but it should require that every authorization gets approved by the end user βœ‹ for clients without secrets, this is a countermeasure against the following threat:

  • Impersonation of public client applications.

5.2.3.3. Issue a client_id Only in Combination with redirect_uri πŸ”—

the authorization server may issue a client_id and bind it to a certain pre-configured redirect_uri 🎯 any authorization request with a different redirect URI gets refused automatically. or, the authorization server should not accept any dynamic redirect URI for that client_id and should always redirect to the well-known pre-configured redirect URI instead. this is a countermeasure for clients without secrets against the following threats:

  • Cross-site scripting attacks
  • Impersonation of public client applications

5.2.3.4. Issue Installation-Specific Client Secrets 🧩

an authorization server may issue separate client identifiers and matching secrets to the different installations of a particular client (aka the software package) 🌸 the effect of this would be to turn otherwise "public" clients back into "confidential" clients, which is so iconic.

for web applications, this could mean creating one client_id and client_secret for each web site where the software package is installed. the provider of that site could request a client id and secret from the authorization server during setup of the web site. this also lets the server validate some properties of that web site, like the redirect URI, the web site URL, and whatever else proves useful πŸ‘€ the web site provider has to make sure the client secret stays secure on the site.

for native applications, things get more complicated, because every copy of a particular application on any device is its own installation πŸ˜΅β€πŸ’« installation-specific secrets here would need a client_id and client_secret obtained either:

  1. during the download process from the application market, or
  2. during installation on the device.

either approach needs an automated mechanism for issuing client ids and secrets, and OAuth doesn't define one yet πŸ₯²

the first approach lets you reach a certain level of trust in the authenticity of the application, whereas the second option only lets you authenticate the installation, not validate the properties of the client. but it would still help prevent several replay attacks πŸ›‘οΈ and installation-specific client_ids and secrets let you selectively revoke all the refresh tokens of one specific installation at once. main character energy for real πŸ‘‘

5.2.3.5. Validate Pre-Registered redirect_uri πŸ“¬

an authorization server should require all clients to register their redirect_uri, and the redirect_uri should be the full URI as defined in [RFC6749]. how that registration happens is out of scope for this document πŸ™…β€β™€οΈ as the core spec says, every actual redirect URI sent with the respective client_id to the end-user authorization endpoint must match the registered redirect URI. when it doesn't match, the authorization server should assume the inbound GET request was sent by an attacker and refuse it 🚨

Note: the authorization server should not redirect the user agent back to the redirect URI of such an authorization request. don't be the server that does that, bestie πŸ™…β€β™€οΈ

validating the pre-registered redirect_uri is a countermeasure against the following threats:

  • Authorization "code" leakage through counterfeit web site: this lets authorization servers detect attack attempts after the first redirect to an end-user authorization endpoint (Section 4.4.1.7).
  • Open redirector attack via a client redirection endpoint (Section 4.1.5).
  • Open redirector phishing attack via an authorization server redirection endpoint (Section 4.2.4).

the underlying assumption here is that an attacker will need to use another redirect URI to get access to the authorization "code". deployments might want to think about an attacker using spoofing attacks against a victim's device to get around this security measure πŸ‘»

Note: pre-registering clients might not scale in some deployments (it's a manual process) or might require dynamic client registration (which isn't specified yet). without dynamic client registration, a pre-registered redirect_uri only works for clients tied to certain deployments set up at development or configuration time. once dynamic resource server discovery is required, the pre-registered redirect_uri may stop being feasible 😭

5.2.3.6. Revoke Client Secrets πŸ—οΈ

an authorization server may revoke a client's secret to stop abuse of a revealed secret 🚫

Note: this measure immediately invalidates any authorization "code" or refresh token issued to the respective client. it might unintentionally affect client identifiers and secrets used across multiple deployments of a particular native or web application 😬

this is a countermeasure against:

  • Abuse of revealed client secrets for private clients

5.2.3.7. Use Strong Client Authentication (e.g., client_assertion/client_token) πŸ”

using an alternative form of authentication, like a client assertion [OAuth-ASSERTIONS], means you don't have to distribute a client_secret anymore ✨ this may require a secure private key store or some other supplemental authentication system, as specified by the client assertion issuer in its authentication process 🧚

5.2.4. End-User Authorization πŸ™‹β€β™€οΈ

this section covers considerations for authorization flows that involve the end user πŸ’–

5.2.4.1. Automatic Processing of Repeated Authorizations Requires Client Validation πŸ€–

authorization servers should NOT automatically process repeat authorizations where the client isn't authenticated through a client secret or some other authentication mechanism. that includes a signed authentication assertion certificate (Section 5.2.3.7) or validation of a pre-registered redirect URI (Section 5.2.3.5) 🫢

5.2.4.2. Informed Decisions Based on Transparency ✨

okay so the authorization server should clearly explain to the end user what's actually happening in the authorization process and what the consequences are 🫢 like, the user should totally get what access they're about to hand over, to which client, and for how long πŸ’… it should also be obvious to the user whether the server can reliably certify certain client properties (like the web site URL or the security policy) πŸ”

5.2.4.3. Validation of Client Properties by End User πŸŽ€

in the authorization process, the user is usually asked to approve a client's request for authorization, and honestly this is a big security mechanism all on its own πŸ’– the end user can help check client properties, like whether the client name the authorization server knows about matches the name of the web site or app they're actually using πŸ‘€ this is especially helpful when the authorization server can't authenticate the client at all πŸ™ˆ it's a countermeasure against:

  • A malicious application
  • A client application masquerading as another client

5.2.4.4. Binding of Authorization "code" to "client_id" πŸ”

the authorization server should bind every authorization "code" to the id of the respective client that started the end-user authorization process πŸ¦‹ this is a countermeasure against:

  • Replay of authorization "codes" with different client credentials, since an attacker cannot use another client_id to exchange an authorization "code" into a token πŸ™…β€β™€οΈ
  • Online guessing of authorization "codes"
Note: This binding should be protected from unauthorized modifications (e.g., using protected memory and/or a secure database). πŸ›‘οΈ

5.2.4.5. Binding of Authorization "code" to "redirect_uri" 🌸

the authorization server should be able to bind every authorization "code" to the actual redirect URI that the client used as its redirect target in the end-user authorization process ✨ this binding should be validated when the client tries to exchange that authorization "code" for an access token πŸ’… it's a countermeasure against authorization "code" leakage through counterfeit web sites, because an attacker can't use another redirect URI to turn the code into a token πŸ™Œ


5.3. Client App Security πŸ’œ

this section covers considerations for client applications 🧚

5.3.1. Don't Store Credentials in Code or Resources Bundled with Software Packages πŸ™ˆ

okay so there's limited benefit in making one client id and secret that's shared by every installation of an app, because there are just so many copies 😭 an app like that would count as a "public" client, since it can't be assumed to keep client secrets πŸ”“ a secret baked into the source code or a resource bundle can't be protected from reverse engineering πŸ’€ and those secrets can't be revoked either, because that would instantly break every single installation πŸ™ƒ plus, since the authorization server can't really trust the client's identifier, it'd be dangerous to show end users how trustworthy the client is 🚩

5.3.2. Use Standard Web Server Protection Measures (for Config Files and Databases) 🏰

use standard web server protection and configuration measures to protect the integrity of the server, its databases, its configuration files, and its other operational components πŸ”’

5.3.3. Store Secrets in Secure Storage πŸ—οΈ

there are different ways to store secrets of all kinds (tokens, client secrets) securely on a device or server ✨

most multi-user operating systems keep the personal storage of different system users separate πŸ‘―β€β™€οΈ and most modern smartphone operating systems even support storing app-specific data in separate areas of the file system, protecting it from other apps πŸ“± apps can also keep confidential data safe by using a user-supplied secret, like a PIN or password πŸ”’

another option is to move refresh token storage to a trusted backend server πŸ–₯️ but this option needs a resilient authentication mechanism between the client and the backend server 🫢

Note: Applications should ensure that confidential data is kept confidential even after reading from secure storage, which typically means keeping this data in the local memory of the application. 🧠

5.3.4. Utilize Device Lock to Prevent Unauthorized Device Access πŸ”

on a typical modern phone there are lots of "device lock" options that add protection when a device is stolen or misplaced πŸ“΅ these include PINs, passwords, and other biometric features like "face recognition" 🀳 they're not all equal, though, in how much security they actually provide βš–οΈ

the "state" parameter is used to link client requests and prevent CSRF attacks, for example attacks against the redirect URI 🚨 an attacker could inject their own authorization "code" or access token, which can make the client use an access token tied to the attacker's protected resources instead of the victim's 😱 (like saving the victim's bank account info to a protected resource the attacker controls) πŸ’Έ

the client should use the "state" request parameter to send the authorization server a value that binds the request to the user agent's authenticated state (for example, a hash of the session cookie used to authenticate the user agent) when it makes an authorization request πŸ“ once authorization has been obtained from the end user, the authorization server redirects the end user's user agent back to the client with that binding value included in the "state" parameter πŸ”

the binding value lets the client check that the request is valid by matching it against the user agent's authenticated state βœ…


5.4. Resource Servers 🌈

the following section details security considerations for resource servers πŸ’–

5.4.1. Authorization Headers πŸ“¨

authorization headers are recognized and specially treated by HTTP proxies and servers πŸ‘€ so using them to send access tokens to resource servers lowers the chance of leakage or unintended storage of authenticated requests in general, and especially of Authorization headers πŸ™Œ

5.4.2. Authenticated Requests πŸͺͺ

an authorization server may bind tokens to a certain client identifier and let resource servers validate that association on resource access πŸ”— this requires the resource server to authenticate the originator of a request as the legitimate owner of a particular token πŸ•΅οΈβ€β™€οΈ there are a few ways to make this happen:

  • The authorization server may associate the client identifier with the token (either internally or in the payload of a self-contained token). The client then uses client certificate-based HTTP authentication on the resource server's endpoint to prove its identity, and the resource server checks the name against the name referenced by the token πŸ“œ
  • Same as the option above, but the client uses its private key to sign the request to the resource server (the public key is either contained in the token or sent along with the request) ✍️
  • Alternatively, the authorization server may issue a token-bound key, which the client uses in a Holder-of-Key proof to authenticate its use of the token 🫧 the resource server gets the secret directly from the authorization server, or the secret is contained in an encrypted section of the token πŸ” that way, the resource server doesn't "know" the client, but it can still validate whether the authorization server issued the token to that client πŸ§šβ€β™€οΈ

authenticated requests are a countermeasure against abuse of tokens by counterfeit resource servers πŸ›‘οΈ

5.4.3. Signed Requests ✍️

a resource server may decide to accept signed requests only, either to replace transport-level security measures or to add to them πŸ’« every signed request should be uniquely identifiable and should not be processed twice by the resource server πŸ”‚ this helps mitigate:

  • modifications of the message and
  • replay attempts

5.5. A Word on User Interaction and User-Installed Apps 🫢

okay, real talk: OAuth is distinctive as a security protocol because its flow usually involves a lot of user interaction, which makes the end user part of the security model 🀯 that creates some big difficulties when defending against the threats we've talked about 😩 some of these points have already come up, but they're worth repeating and highlighting here πŸ“£

  • End users must understand what they are being asked to approve (see Section 5.2.4.2). Users often don't have the expertise to understand what it really means to say "yes" to an authorization request, and they're likely not to notice subtle differences in the wording of requests πŸ‘οΈ malicious software can confuse the user and trick them into approving almost anything πŸ˜΅β€πŸ’«
  • End-user devices are prone to software compromise πŸ’» this has been a long-standing problem, with frequent attacks on web browsers and other parts of the user's system πŸ•ΈοΈ but with user-installed "apps" getting more and more popular, the threat from compromised or malicious end-user software is very strong and very difficult to mitigate 🚨
  • Be aware that users will demand to install and run such apps, and that compromised or malicious ones can steal credentials at many points in the data flow πŸ₯² they can intercept the very user login credentials that OAuth is designed to protect πŸ”‘ they can request authorization far beyond what they led the user to understand and approve πŸ™€ and they can automate a response on the user's behalf, hiding the whole process πŸ€– no solution is offered here, because none is known; this stays in the space between better security and better usability βš–οΈ
  • Addressing these issues by restricting the use of user-installed software may be practical in some limited environments and can be used as a countermeasure in those cases 🧱 such restrictions are not practical in the general case, so mechanisms for after-the-fact recovery should be in place πŸ”„
  • While end users are mostly incapable of properly vetting the applications they load onto their devices, the people who deploy authorization servers might have tools at their disposal to mitigate malicious clients 🧰 for example, a well-run authorization server must only assert client properties to the end user that it is effectively capable of validating, explicitly point out which properties it cannot validate, and indicate to the end user the risk associated with granting access to the particular client 🫑

6. Acknowledgements πŸ’Œ

we'd like to thank Stephen Farrell, Barry Leiba, Hui-Lan Lu, Francisco Corella, Peifung E. Lam, Shane B. Weeden, Skylar Woodward, Niv Steingarten, Tim Bray, and James H. Manger for their comments and contributions πŸ₯°πŸŽ€

7. References πŸ“š

7.1. Normative References πŸ”—

[RFC6749]  Hardt, D., "The OAuth 2.0 Authorization Framework",
           RFC 6749, October 2012.

[RFC6750]  Jones, M. and D. Hardt, "The OAuth 2.0 Authorization
           Framework: Bearer Token Usage", RFC 6750, October 2012.

7.2. Informative References ✨

okay bestie, this is the reading list section πŸ¦‹ these are the extra sources the spec points to for background, not stuff you have to follow to build the thing. the ones marked Work in Progress were still drafts when this was written πŸ’…

  • [Framebusting] Rydstedt, G., Bursztein, Boneh, D., and C. Jackson, "Busting Frame Busting: a Study of Clickjacking Vulnerabilities on Popular Sites", IEEE 3rd Web 2.0 Security and Privacy Workshop, May 2010, <http://elie.im/publication/busting-frame-busting-a-study-of-clickjacking-vulnerabilities-on-popular-sites>. the clickjacking paper, and it's giving serious research energy πŸ”₯
  • [IMEI] 3GPP, "International Mobile station Equipment Identities (IMEI)", 3GPP TS 22.016 11.0.0, September 2012, <http://www.3gpp.org/ftp/Specs/html-info/22016.htm>. the phone-identity spec πŸ“±
  • [OASIS.saml-core-2.0-os] Cantor, S., Ed., Kemp, J., Ed., Philpott, R., Ed., and E. Maler, Ed., "Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0", OASIS Standard saml-core-2.0-os, March 2005, <http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf>. SAML 2.0 core, the big one 🌸
  • [OASIS.sstc-saml-bindings-1.1] Maler, E., Ed., Mishra, P., Ed., and R. Philpott, Ed., "Bindings and Profiles for the OASIS Security Assertion Markup Language (SAML) V1.1", September 2003, <http://www.oasis-open.org/committees/download.php/3405/oasis-sstc-saml-bindings-1.1.pdf>. SAML 1.1 bindings and profiles 🧚
  • [OASIS.sstc-sec-analysis-response-01] Linn, J., Ed., and P. Mishra, Ed., "SSTC Response to "Security Analysis of the SAML Single Sign-on Browser/Artifact Profile"", January 2005, <http://www.oasis-open.org/committees/download.php/11191/sstc-gross-sec-analysis-response-01.pdf>. the committee's reply to the security analysis below, so the drama continues πŸ“
  • [OAuth-ASSERTIONS] Campbell, B., Mortimore, C., Jones, M., and Y. Goland, "Assertion Framework for OAuth 2.0", Work in Progress, December 2012. draft energy πŸ¦‹
  • [OAuth-HTTP-MAC] Richer, J., Ed., Mills, W., Ed., and H. Tschofenig, Ed., "OAuth 2.0 Message Authentication Code (MAC) Tokens", Work in Progress, November 2012. still cooking 🍳
  • [OAuth-JWT] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", Work in Progress, December 2012. JWT, a classic πŸ’œ
  • [OAuth-REVOCATION] Lodderstedt, T., Ed., Dronia, S., and M. Scurtescu, "Token Revocation", Work in Progress, November 2012. the revoking-tokens draft 🫢
  • [OPENID] "OpenID Foundation Home Page", <http://openid.net/>. the OpenID home page 🌈
  • [OWASP] "Open Web Application Security Project Home Page", <https://www.owasp.org/>. OWASP, the security community you should absolutely know πŸ›‘οΈ
  • [Portable-Contacts] Smarr, J., "Portable Contacts 1.0 Draft C", August 2008, <http://portablecontacts.net/>. the contacts format draft πŸ“‡
  • [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999. the old HTTP/1.1 spec 🌷
  • [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000. HTTP over TLS, the HTTPS pairing πŸ”
  • [RFC4086] Eastlake, D., Schiller, J., and S. Crocker, "Randomness Requirements for Security", BCP 106, RFC 4086, June 2005. randomness, but make it a whole RFC 🎲
  • [RFC4120] Neuman, C., Yu, T., Hartman, S., and K. Raeburn, "The Kerberos Network Authentication Service (V5)", RFC 4120, July 2005. Kerberos, the three-headed dog of auth πŸ•
  • [RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, December 2005. the IPsec architecture 🧱
  • [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, August 2008. TLS 1.2 πŸ’–
  • [SSL-Latency] Sissel, J., Ed., "SSL handshake latency and HTTPS optimizations", June 2010. how to make the handshake less slow 🐒
  • [Sec-Analysis] Gross, T., "Security Analysis of the SAML Single Sign-on Browser/Artifact Profile", 19th Annual Computer Security Applications Conference, Las Vegas, December 2003. the tea on SAML's browser profile β˜•
  • [X-Frame-Options] Ross, D. and T. Gondrom, "HTTP Header X-Frame-Options", Work in Progress, October 2012. the anti-framing header, still a draft at this point πŸ–ΌοΈ
  • [iFrame] World Wide Web Consortium, "Frames in HTML documents", W3C HTML 4.01, December 1999, <http://www.w3.org/TR/html4/present/frames.html#h-16.5>. the frames spec from the HTML 4.01 era πŸŽ€

Authors' Addresses πŸŽ€

Torsten Lodderstedt (editor) Deutsche Telekom AG

EMail: torsten@lodderstedt.net

Mark McGloin IBM

EMail: mark.mcgloin@ie.ibm.com

Phil Hunt Oracle Corporation

EMail: phil.hunt@yahoo.com

and that's the whole spec, bestie 😭✨ you made it through all 14 parts. the people behind it are right there at the bottom 🫢

πŸ“¦ where this page comes from