| < draft-ietf-oauth-browser-based-apps-07.txt | draft-ietf-oauth-browser-based-apps-08.txt > | |||
|---|---|---|---|---|
| Open Authentication Protocol A. Parecki | Open Authentication Protocol A. Parecki | |||
| Internet-Draft Okta | Internet-Draft Okta | |||
| Intended status: Best Current Practice D. Waite | Intended status: Best Current Practice D. Waite | |||
| Expires: April 5, 2021 Ping Identity | Expires: November 18, 2021 Ping Identity | |||
| October 02, 2020 | May 17, 2021 | |||
| OAuth 2.0 for Browser-Based Apps | OAuth 2.0 for Browser-Based Apps | |||
| draft-ietf-oauth-browser-based-apps-07 | draft-ietf-oauth-browser-based-apps-08 | |||
| Abstract | Abstract | |||
| This specification details the security considerations and best | This specification details the security considerations and best | |||
| practices that must be taken into account when developing browser- | practices that must be taken into account when developing browser- | |||
| based applications that use OAuth 2.0. | based applications that use OAuth 2.0. | |||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| skipping to change at page 1, line 33 ¶ | skipping to change at page 1, line 33 ¶ | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on April 5, 2021. | This Internet-Draft will expire on November 18, 2021. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2020 IETF Trust and the persons identified as the | Copyright (c) 2021 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| skipping to change at page 2, line 29 ¶ | skipping to change at page 2, line 29 ¶ | |||
| Application . . . . . . . . . . . . . . . . . . . . . . . 9 | Application . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 7.2. Handling the Authorization Code Redirect . . . . . . . . 10 | 7.2. Handling the Authorization Code Redirect . . . . . . . . 10 | |||
| 8. Refresh Tokens . . . . . . . . . . . . . . . . . . . . . . . 10 | 8. Refresh Tokens . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 9. Security Considerations . . . . . . . . . . . . . . . . . . . 11 | 9. Security Considerations . . . . . . . . . . . . . . . . . . . 11 | |||
| 9.1. Registration of Browser-Based Apps . . . . . . . . . . . 11 | 9.1. Registration of Browser-Based Apps . . . . . . . . . . . 11 | |||
| 9.2. Client Authentication . . . . . . . . . . . . . . . . . . 11 | 9.2. Client Authentication . . . . . . . . . . . . . . . . . . 11 | |||
| 9.3. Client Impersonation . . . . . . . . . . . . . . . . . . 12 | 9.3. Client Impersonation . . . . . . . . . . . . . . . . . . 12 | |||
| 9.4. Cross-Site Request Forgery Protections . . . . . . . . . 12 | 9.4. Cross-Site Request Forgery Protections . . . . . . . . . 12 | |||
| 9.5. Authorization Server Mix-Up Mitigation . . . . . . . . . 12 | 9.5. Authorization Server Mix-Up Mitigation . . . . . . . . . 12 | |||
| 9.6. Cross-Domain Requests . . . . . . . . . . . . . . . . . . 13 | 9.6. Cross-Domain Requests . . . . . . . . . . . . . . . . . . 13 | |||
| 9.7. Content-Security Policy . . . . . . . . . . . . . . . . . 13 | 9.7. Content Security Policy . . . . . . . . . . . . . . . . . 13 | |||
| 9.8. OAuth Implicit Flow . . . . . . . . . . . . . . . . . . . 13 | 9.8. OAuth Implicit Flow . . . . . . . . . . . . . . . . . . . 13 | |||
| 9.8.1. Attacks on the Implicit Flow . . . . . . . . . . . . 13 | 9.8.1. Attacks on the Implicit Flow . . . . . . . . . . . . 14 | |||
| 9.8.2. Countermeasures . . . . . . . . . . . . . . . . . . . 15 | 9.8.2. Countermeasures . . . . . . . . . . . . . . . . . . . 15 | |||
| 9.8.3. Disadvantages of the Implicit Flow . . . . . . . . . 15 | 9.8.3. Disadvantages of the Implicit Flow . . . . . . . . . 15 | |||
| 9.8.4. Historic Note . . . . . . . . . . . . . . . . . . . . 16 | 9.8.4. Historic Note . . . . . . . . . . . . . . . . . . . . 16 | |||
| 9.9. Additional Security Considerations . . . . . . . . . . . 16 | 9.9. Additional Security Considerations . . . . . . . . . . . 16 | |||
| 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 | 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 | |||
| 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 | 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 17 | |||
| 11.1. Normative References . . . . . . . . . . . . . . . . . . 16 | 11.1. Normative References . . . . . . . . . . . . . . . . . . 17 | |||
| 11.2. Informative References . . . . . . . . . . . . . . . . . 17 | 11.2. Informative References . . . . . . . . . . . . . . . . . 18 | |||
| Appendix A. Server Support Checklist . . . . . . . . . . . . . . 17 | Appendix A. Server Support Checklist . . . . . . . . . . . . . . 18 | |||
| Appendix B. Document History . . . . . . . . . . . . . . . . . . 18 | Appendix B. Document History . . . . . . . . . . . . . . . . . . 18 | |||
| Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 20 | Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 21 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 21 | |||
| 1. Introduction | 1. Introduction | |||
| This specification describes the current best practices for | This specification describes the current best practices for | |||
| implementing OAuth 2.0 authorization flows in applications executing | implementing OAuth 2.0 authorization flows in applications executing | |||
| in a browser. | in a browser. | |||
| For native application developers using OAuth 2.0 and OpenID Connect, | For native application developers using OAuth 2.0 and OpenID Connect, | |||
| an IETF BCP (best current practice) was published that guides | an IETF BCP (best current practice) was published that guides | |||
| integration of these technologies. This document is formally known | integration of these technologies. This document is formally known | |||
| skipping to change at page 3, line 17 ¶ | skipping to change at page 3, line 17 ¶ | |||
| adopting these practices. [RFC8252] makes specific recommendations | adopting these practices. [RFC8252] makes specific recommendations | |||
| for how to securely implement OAuth in native applications, including | for how to securely implement OAuth in native applications, including | |||
| incorporating additional OAuth extensions where needed. | incorporating additional OAuth extensions where needed. | |||
| OAuth 2.0 for Browser-Based Apps addresses the similarities between | OAuth 2.0 for Browser-Based Apps addresses the similarities between | |||
| implementing OAuth for native apps and browser-based apps, and | implementing OAuth for native apps and browser-based apps, and | |||
| includes additional considerations when running in a browser. This | includes additional considerations when running in a browser. This | |||
| is primarily focused on OAuth, except where OpenID Connect provides | is primarily focused on OAuth, except where OpenID Connect provides | |||
| additional considerations. | additional considerations. | |||
| Many of these recommendations are derived from the OAuth 2.0 Security | ||||
| Best Current Practice [oauth-security-topics] and browser-based apps | ||||
| are expected to follow those recommendations as well. This draft | ||||
| expands on and further restricts various recommendations in | ||||
| [oauth-security-topics]. | ||||
| 2. Notational Conventions | 2. Notational Conventions | |||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
| "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
| "OPTIONAL" in this document are to be interpreted as described in | "OPTIONAL" in this document are to be interpreted as described in | |||
| [RFC2119]. | [RFC2119]. | |||
| 3. Terminology | 3. Terminology | |||
| In addition to the terms defined in referenced specifications, this | In addition to the terms defined in referenced specifications, this | |||
| skipping to change at page 3, line 44 ¶ | skipping to change at page 3, line 50 ¶ | |||
| JavaScript. Also sometimes referred to as a "single-page | JavaScript. Also sometimes referred to as a "single-page | |||
| application", or "SPA". | application", or "SPA". | |||
| 4. Overview | 4. Overview | |||
| At the time that OAuth 2.0 [RFC6749] and [RFC6750] were created, | At the time that OAuth 2.0 [RFC6749] and [RFC6750] were created, | |||
| browser-based JavaScript applications needed a solution that strictly | browser-based JavaScript applications needed a solution that strictly | |||
| complied with the same-origin policy. Common deployments of OAuth | complied with the same-origin policy. Common deployments of OAuth | |||
| 2.0 involved an application running on a different domain than the | 2.0 involved an application running on a different domain than the | |||
| authorization server, so it was historically not possible to use the | authorization server, so it was historically not possible to use the | |||
| authorization code flow which would require a cross-origin POST | Authorization Code flow which would require a cross-origin POST | |||
| request. This was one of the motivations for the definition of the | request. This was one of the motivations for the definition of the | |||
| implicit flow, which returns the access token in the front channel | Implicit flow, which returns the access token in the front channel | |||
| via the fragment part of the URL, bypassing the need for a cross- | via the fragment part of the URL, bypassing the need for a cross- | |||
| origin POST request. | origin POST request. | |||
| However, there are several drawbacks to the implicit flow, generally | However, there are several drawbacks to the Implicit flow, generally | |||
| involving vulnerabilities associated with the exposure of the access | involving vulnerabilities associated with the exposure of the access | |||
| token in the URL. See Section 9.8 for an analysis of these attacks | token in the URL. See Section 9.8 for an analysis of these attacks | |||
| and the drawbacks of using the implicit flow in browsers. Additional | and the drawbacks of using the Implicit flow in browsers. Additional | |||
| attacks and security considerations can be found in | attacks and security considerations can be found in | |||
| [oauth-security-topics]. | [oauth-security-topics]. | |||
| In recent years, widespread adoption of Cross-Origin Resource Sharing | In recent years, widespread adoption of Cross-Origin Resource Sharing | |||
| (CORS), which enables exceptions to the same-origin policy, allows | (CORS), which enables exceptions to the same-origin policy, allows | |||
| browser-based apps to use the OAuth 2.0 authorization code flow and | browser-based apps to use the OAuth 2.0 Authorization Code flow and | |||
| make a POST request to exchange the authorization code for an access | make a POST request to exchange the authorization code for an access | |||
| token at the token endpoint. In this flow, the access token is never | token at the token endpoint. In this flow, the access token is never | |||
| exposed in the less secure front-channel. Furthermore, adding PKCE | exposed in the less secure front channel. Furthermore, adding PKCE | |||
| to the flow ensures that even if an authorization code is | to the flow ensures that even if an authorization code is | |||
| intercepted, it is unusable by an attacker. | intercepted, it is unusable by an attacker. | |||
| For this reason, and from other lessons learned, the current best | For this reason, and from other lessons learned, the current best | |||
| practice for browser-based applications is to use the OAuth 2.0 | practice for browser-based applications is to use the OAuth 2.0 | |||
| authorization code flow with PKCE. | Authorization Code flow with PKCE. | |||
| Browser-based applications: | Browser-based applications: | |||
| o MUST use the OAuth 2.0 authorization code flow with the PKCE | o MUST use the OAuth 2.0 Authorization Code flow with the PKCE | |||
| extension when obtaining an access token | extension when obtaining an access token | |||
| o MUST Protect themselves against CSRF attacks by either: | o MUST Protect themselves against CSRF attacks by either: | |||
| * ensuring the authorization server supports PKCE, or | * ensuring the authorization server supports PKCE, or | |||
| * by using the OAuth 2.0 "state" parameter or the OpenID Connect | * by using the OAuth 2.0 "state" parameter or the OpenID Connect | |||
| "nonce" parameter to carry one-time use CSRF tokens | "nonce" parameter to carry one-time use CSRF tokens | |||
| o MUST Register one or more redirect URIs, and use only exact | o MUST Register one or more redirect URIs, and use only exact | |||
| registered redirect URIs in authorization requests | registered redirect URIs in authorization requests | |||
| OAuth 2.0 authorization servers: | OAuth 2.0 authorization servers supporting browser-based | |||
| applications: | ||||
| o MUST Require exact matching of registered redirect URIs | o MUST Require exact matching of registered redirect URIs | |||
| o MUST Support the PKCE extension | o MUST Support the PKCE extension | |||
| o MUST NOT issue access tokens in the authorization response | o MUST NOT issue access tokens in the authorization response | |||
| o If issuing refresh tokens to browser-based applications, then: | ||||
| o If issuing refresh tokens to browser-based apps, then: | * MUST rotate refresh tokens on each use or use sender- | |||
| constrained refresh tokens, and | ||||
| * SHOULD rotate refresh tokens on each use, and | ||||
| * MUST set a maximum lifetime on refresh tokens or expire if they | * MUST set a maximum lifetime on refresh tokens or expire if they | |||
| are not used in some amount of time | are not used in some amount of time | |||
| 5. First-Party Applications | 5. First-Party Applications | |||
| While OAuth was initially created to allow third-party applications | While OAuth was initially created to allow third-party applications | |||
| to access an API on behalf of a user, it has proven to be useful in a | to access an API on behalf of a user, it has proven to be useful in a | |||
| first-party scenario as well. First-party apps are applications | first-party scenario as well. First-party apps are applications | |||
| where the same organization provides both the API and the | where the same organization provides both the API and the | |||
| skipping to change at page 5, line 26 ¶ | skipping to change at page 5, line 33 ¶ | |||
| application actually be developed by the same company; a mobile | application actually be developed by the same company; a mobile | |||
| banking application developed by a contractor that is branded as the | banking application developed by a contractor that is branded as the | |||
| bank's application is still considered a first-party application.) | bank's application is still considered a first-party application.) | |||
| The first-party app consideration is about the user's relationship to | The first-party app consideration is about the user's relationship to | |||
| the application and the service. | the application and the service. | |||
| To conform to this best practice, first-party applications using | To conform to this best practice, first-party applications using | |||
| OAuth or OpenID Connect MUST use a redirect-based flow (such as the | OAuth or OpenID Connect MUST use a redirect-based flow (such as the | |||
| OAuth Authorization Code flow) as described later in this document. | OAuth Authorization Code flow) as described later in this document. | |||
| The Resource Owner Password Grant MUST NOT be used, as described in | The resource owner password credentials grant MUST NOT be used, as | |||
| [oauth-security-topics] section 3.4. Instead, by using the | described in [oauth-security-topics] Section 2.4. Instead, by using | |||
| Authorization Code flow and redirecting the user to the authorization | the Authorization Code flow and redirecting the user to the | |||
| server, this provides the authorization server the opportunity to | authorization server, this provides the authorization server the | |||
| prompt the user for multi-factor authentication options, take | opportunity to prompt the user for multi-factor authentication | |||
| advantage of single-sign-on sessions, or use third-party identity | options, take advantage of single sign-on sessions, or use third- | |||
| providers. In contrast, the Password grant does not provide any | party identity providers. In contrast, the resource owner password | |||
| built-in mechanism for these, and would instead be extended with | credentials grant does not provide any built-in mechanism for these, | |||
| custom code. | and would instead be extended with custom code. | |||
| 6. Application Architecture Patterns | 6. Application Architecture Patterns | |||
| There are three primary architectural patterns available when | There are three primary architectural patterns available when | |||
| building browser-based applications. | building browser-based applications. | |||
| o a JavaScript application that has methods of sharing data with | o a JavaScript application that has methods of sharing data with | |||
| resource servers, such as using common-domain cookies | resource servers, such as using common-domain cookies | |||
| o a JavaScript application with a backend | o a JavaScript application with a backend | |||
| skipping to change at page 5, line 45 ¶ | skipping to change at page 6, line 4 ¶ | |||
| 6. Application Architecture Patterns | 6. Application Architecture Patterns | |||
| There are three primary architectural patterns available when | There are three primary architectural patterns available when | |||
| building browser-based applications. | building browser-based applications. | |||
| o a JavaScript application that has methods of sharing data with | o a JavaScript application that has methods of sharing data with | |||
| resource servers, such as using common-domain cookies | resource servers, such as using common-domain cookies | |||
| o a JavaScript application with a backend | o a JavaScript application with a backend | |||
| o a JavaScript application with no backend, accessing resource | o a JavaScript application with no backend, accessing resource | |||
| servers directly | servers directly | |||
| These three architectures have different use cases and | These three architectures have different use cases and | |||
| considerations. | considerations. | |||
| 6.1. Browser-Based Apps that Can Share Data with the Resource Server | 6.1. Browser-Based Apps that Can Share Data with the Resource Server | |||
| For simple system architectures, such as when the JavaScript | For simple system architectures, such as when the JavaScript | |||
| application is served from a domain that can share cookies with the | application is served from a domain that can share cookies with the | |||
| domain of the API (resource server), OAuth adds additional attack | domain of the API (resource server), OAuth adds additional attack | |||
| vectors that could be avoided with a different solution. | vectors that could be avoided with a different solution. | |||
| In particular, using any redirect-based mechanism of obtaining an | In particular, using any redirect-based mechanism of obtaining an | |||
| access token enables the redirect-based attacks described in | access token enables the redirect-based attacks described in | |||
| [oauth-security-topics], but if the application, authorization server | [oauth-security-topics] Section 4, but if the application, | |||
| and resource server share a domain, then it is unnecessary to use a | authorization server and resource server share a domain, then it is | |||
| redirect mechanism to communicate between them. | unnecessary to use a redirect mechanism to communicate between them. | |||
| An additional concern with handling access tokens in a browser is | An additional concern with handling access tokens in a browser is | |||
| that as of the date of this publication, there is no secure storage | that as of the date of this publication, there is no secure storage | |||
| mechanism where JavaScript code can keep the access token to be later | mechanism where JavaScript code can keep the access token to be later | |||
| used in an API request. Using an OAuth flow results in the | used in an API request. Using an OAuth flow results in the | |||
| JavaScript code getting an access token, needing to store it | JavaScript code getting an access token, needing to store it | |||
| somewhere, and then retrieve it to make an API request. | somewhere, and then retrieve it to make an API request. | |||
| Instead, a more secure design is to use an HTTP-only cookie between | Instead, a more secure design is to use an HTTP-only cookie between | |||
| the JavaScript application and API so that the JavaScript code can't | the JavaScript application and API so that the JavaScript code can't | |||
| access the cookie value itself. Additionally, the SameSite cookie | access the cookie value itself. The Secure cookie attribute should | |||
| attribute can be used to prevent CSRF attacks, or alternatively, the | be used to ensure the cookie is not included in unencrypted HTTP | |||
| application and API could be written to use anti-CSRF tokens. | requests. Additionally, the SameSite cookie attribute can be used to | |||
| prevent CSRF attacks, or alternatively, the application and API could | ||||
| be written to use anti-CSRF tokens. | ||||
| OAuth was originally created for third-party or federated access to | OAuth was originally created for third-party or federated access to | |||
| APIs, so it may not be the best solution in a common-domain | APIs, so it may not be the best solution in a common-domain | |||
| deployment. That said, using OAuth even in a common-domain | deployment. That said, using OAuth even in a common-domain | |||
| architecture does mean you can more easily rearchitect things later, | architecture does mean you can more easily rearchitect things later, | |||
| such as if you were to later add a new domain to the system. | such as if you were to later add a new domain to the system. | |||
| 6.2. JavaScript Applications with a Backend | 6.2. JavaScript Applications with a Backend | |||
| +-------------+ +--------------+ +---------------+ | +-------------+ +--------------+ +---------------+ | |||
| | | | | | | | | | | | | | | |||
| skipping to change at page 7, line 32 ¶ | skipping to change at page 7, line 32 ¶ | |||
| | ^ ^ + ^ + | | ^ ^ + ^ + | |||
| | (A)| (C)| (E)| (F)| |(H) | | (A)| (C)| (E)| (F)| |(H) | |||
| v v + v + v | v v + v + v | |||
| +-------------------------------------------------+ | +-------------------------------------------------+ | |||
| | | | | | | |||
| | Browser | | | Browser | | |||
| | | | | | | |||
| +-------------------------------------------------+ | +-------------------------------------------------+ | |||
| In this architecture, the JavaScript code is loaded from a dynamic | In this architecture, commonly referred to as "backend for frontend" | |||
| Application Server (A) that also has the ability to execute code | or "BFF", the JavaScript code is loaded from a dynamic Application | |||
| itself. This enables the ability to keep all of the steps involved | Server (A) that also has the ability to execute code itself. This | |||
| in obtaining an access token outside of the JavaScript application. | enables the ability to keep all of the steps involved in obtaining an | |||
| access token outside of the JavaScript application. | ||||
| In this case, the Application Server initiates the OAuth flow itself, | In this case, the Application Server initiates the OAuth flow itself, | |||
| by redirecting the browser to the authorization endpoint (B). When | by redirecting the browser to the authorization endpoint (B). When | |||
| the user is redirected back, the browser delivers the authorization | the user is redirected back, the browser delivers the authorization | |||
| code to the application server (C), where it can then exchange it for | code to the application server (C), where it can then exchange it for | |||
| an access token at the token endpoint (D) using its client secret. | an access token at the token endpoint (D) using its client secret. | |||
| The application server then keeps the access token and refresh token | The application server then keeps the access token and refresh token | |||
| stored internally, and creates a separate session with the browser- | stored internally, and creates a separate session with the browser- | |||
| based app via a traditional browser cookie (E). | based app via a traditional browser cookie (E). | |||
| When the JavaScript application in the browser wants to make a | When the JavaScript application in the browser wants to make a | |||
| request to the Resource Server, it instead makes the request to the | request to the Resource Server, it instead makes the request to the | |||
| Application Server (F), and the Application Server will make the | Application Server (F), and the Application Server will make the | |||
| request with the access token to the Resource Server (H), and forward | request with the access token to the Resource Server (G), and forward | |||
| the response (H) back to the browser. | the response (H) back to the browser. | |||
| (Common examples of this architecture are an Angular front-end with a | (Common examples of this architecture are an Angular front-end with a | |||
| .NET backend, or a React front-end with a Spring Boot backend.) | .NET backend, or a React front-end with a Spring Boot backend.) | |||
| The Application Server SHOULD be considered a confidential client, | The Application Server SHOULD be considered a confidential client, | |||
| and issued its own client secret. The Application Server SHOULD use | and issued its own client secret. The Application Server SHOULD use | |||
| the OAuth 2.0 Authorization Code grant with PKCE to initiate a | the OAuth 2.0 Authorization Code grant with PKCE to initiate a | |||
| request for an access token. | request for an access token. Detailed recommendations for | |||
| confidential clients can be found in [oauth-security-topics] | ||||
| Section 2.1.1. | ||||
| In this scenario, the session between the browser and Application | ||||
| Server SHOULD be a session cookie provided by the Application Server. | ||||
| Security of the connection between code running in the browser and | Security of the connection between code running in the browser and | |||
| this Application Server is assumed to utilize browser-level | this Application Server is assumed to utilize browser-level | |||
| protection mechanisms. Details are out of scope of this document, | protection mechanisms. Details are out of scope of this document, | |||
| but many recommendations can be found in the OWASP Cheat Sheet series | but many recommendations can be found in the OWASP Cheat Sheet series | |||
| (https://cheatsheetseries.owasp.org/), such as setting an HTTP-only | (https://cheatsheetseries.owasp.org/), such as setting an HTTP-only | |||
| and Secure cookie to authenticate the session between the browser and | and Secure cookie to authenticate the session between the browser and | |||
| Application Server. | Application Server. | |||
| In this scenario, the session between the browser and Application | ||||
| Server SHOULD be a session cookie provided by the Application Server. | ||||
| 6.3. JavaScript Applications without a Backend | 6.3. JavaScript Applications without a Backend | |||
| +---------------+ +--------------+ | +---------------+ +--------------+ | |||
| | | | | | | | | | | |||
| | Authorization | | Resource | | | Authorization | | Resource | | |||
| | Server | | Server | | | Server | | Server | | |||
| | | | | | | | | | | |||
| +---------------+ +--------------+ | +---------------+ +--------------+ | |||
| ^ + ^ + | ^ ^ ^ + | |||
| | | | | | | | | | | |||
| |(B) |(C) |(D) |(E) | |(B) |(C) |(D) |(E) | |||
| | | | | | | | | | | |||
| | | | | | | | | | | |||
| + v + v | + v + v | |||
| +-----------------+ +-------------------------------+ | +-----------------+ +-------------------------------+ | |||
| | | (A) | | | | | (A) | | | |||
| | Static Web Host | +-----> | Browser | | | Static Web Host | +-----> | Browser | | |||
| | | | | | | | | | | |||
| +-----------------+ +-------------------------------+ | +-----------------+ +-------------------------------+ | |||
| In this architecture, the JavaScript code is first loaded from a | In this architecture, the JavaScript code is first loaded from a | |||
| static web host into the browser (A), and the application then runs | static web host into the browser (A), and the application then runs | |||
| in the browser. This application is considered a public client, | in the browser. This application is considered a public client, | |||
| since there is no way to issue it a client secret and there is no | since there is no way to issue it a client secret and there is no | |||
| other secure client authentication mechanism available in the | other secure client authentication mechanism available in the | |||
| browser. | browser. | |||
| The code in the browser initiates the authorization code flow with | The code in the browser initiates the Authorization Code flow with | |||
| the PKCE extension (described in Section 7) (B) above, and obtains an | the PKCE extension (described in Section 7) (B) above, and obtains an | |||
| access token via a POST request (C). The JavaScript app is then | access token via a POST request (C). The JavaScript application is | |||
| responsible for storing the access token (and optional refresh token) | then responsible for storing the access token (and optional refresh | |||
| securely using appropriate browser APIs. | token) as securely as possible using appropriate browser APIs. As of | |||
| the date of this publication there is no browser API that allows to | ||||
| store tokens in a completely secure way. | ||||
| When the JavaScript application in the browser wants to make a | When the JavaScript application in the browser wants to make a | |||
| request to the Resource Server, it can include the access token in | request to the Resource Server, it can interact with the Resource | |||
| the request (D) and make the request directly. | Server directly. It includes the access token in the request (D) and | |||
| receives the Resource Server's response (E). | ||||
| In this scenario, the Authorization Server and Resource Server MUST | In this scenario, the Authorization Server and Resource Server MUST | |||
| support the necessary CORS headers to enable the JavaScript code to | support the necessary CORS headers to enable the JavaScript code to | |||
| make this POST request from the domain on which the script is | make this POST request from the domain on which the script is | |||
| executing. (See Section 9.6 for additional details.) | executing. (See Section 9.6 for additional details.) | |||
| 7. Authorization Code Flow | 7. Authorization Code Flow | |||
| Public browser-based apps that use the authorization code grant type | Browser-based applications that are public clients and use the | |||
| described in Section 4.1 of OAuth 2.0 [RFC6749] MUST also follow | Authorization Code grant type described in Section 4.1 of OAuth 2.0 | |||
| these additional requirements described in this section. | [RFC6749] MUST also follow these additional requirements described in | |||
| this section. | ||||
| 7.1. Initiating the Authorization Request from a Browser-Based | 7.1. Initiating the Authorization Request from a Browser-Based | |||
| Application | Application | |||
| Public browser-based apps MUST implement the Proof Key for Code | Browser-based applications that are public clients MUST implement the | |||
| Exchange (PKCE [RFC7636]) extension when obtaining an access token, | Proof Key for Code Exchange (PKCE [RFC7636]) extension when obtaining | |||
| and authorization servers MUST support and enforce PKCE for such | an access token, and authorization servers MUST support and enforce | |||
| clients. | PKCE for such clients. | |||
| The PKCE extension prevents an attack where the authorization code is | The PKCE extension prevents an attack where the authorization code is | |||
| intercepted and exchanged for an access token by a malicious client, | intercepted and exchanged for an access token by a malicious client, | |||
| by providing the authorization server with a way to verify the same | by providing the authorization server with a way to verify the client | |||
| client instance that exchanges the authorization code is the same one | instance that exchanges the authorization code is the same one that | |||
| that initiated the flow. | initiated the flow. | |||
| Browser-based apps MUST prevent CSRF attacks against their redirect | Browser-based applications MUST prevent CSRF attacks against their | |||
| URI. This can be accomplished by any of the below: | redirect URI. This can be accomplished by any of the below: | |||
| o using PKCE, and confirming that the authorization server supports | o using PKCE, and confirming that the authorization server supports | |||
| PKCE | PKCE | |||
| o using a unique value for the OAuth 2.0 "state" parameter | o using a unique value for the OAuth 2.0 "state" parameter | |||
| o if the application is using OpenID Connect, by using the OpenID | o if the application is using OpenID Connect, by using the OpenID | |||
| Connect "nonce" parameter | Connect "nonce" parameter | |||
| Browser-based apps MUST follow the recommendations in | ||||
| [oauth-security-topics] Section 2.1 to protect themselves during | ||||
| redirect flows. | ||||
| 7.2. Handling the Authorization Code Redirect | 7.2. Handling the Authorization Code Redirect | |||
| Authorization servers MUST require an exact match of a registered | Authorization servers MUST require an exact match of a registered | |||
| redirect URI. | redirect URI. As described in [oauth-security-topics] Section 4.1.1. | |||
| this helps to prevent attacks targeting the authorization code. | ||||
| 8. Refresh Tokens | 8. Refresh Tokens | |||
| Refresh tokens provide a way for applications to obtain a new access | Refresh tokens provide a way for applications to obtain a new access | |||
| token when the initial access token expires. With public clients, | token when the initial access token expires. With public clients, | |||
| the risk of a leaked refresh token is greater than leaked access | the risk of a leaked refresh token is greater than leaked access | |||
| tokens, since an attacker may be able to continue using the stolen | tokens, since an attacker may be able to continue using the stolen | |||
| refresh token to obtain new access tokens potentially without being | refresh token to obtain new access tokens potentially without being | |||
| detectable by the authorization server. | detectable by the authorization server. | |||
| skipping to change at page 10, line 34 ¶ | skipping to change at page 10, line 36 ¶ | |||
| opportunities by which a refresh token can be leaked, just as with | opportunities by which a refresh token can be leaked, just as with | |||
| access tokens. As such, these applications are considered a higher | access tokens. As such, these applications are considered a higher | |||
| risk for handling refresh tokens. | risk for handling refresh tokens. | |||
| Authorization servers may choose whether or not to issue refresh | Authorization servers may choose whether or not to issue refresh | |||
| tokens to browser-based applications. [oauth-security-topics] | tokens to browser-based applications. [oauth-security-topics] | |||
| describes some additional requirements around refresh tokens on top | describes some additional requirements around refresh tokens on top | |||
| of the recommendations of [RFC6749]. Applications and authorization | of the recommendations of [RFC6749]. Applications and authorization | |||
| servers conforming to this BCP MUST also follow the recommendations | servers conforming to this BCP MUST also follow the recommendations | |||
| in [oauth-security-topics] around refresh tokens if refresh tokens | in [oauth-security-topics] around refresh tokens if refresh tokens | |||
| are issued to browser-based apps. | are issued to browser-based applications. | |||
| In particular, authorization servers: | In particular, authorization servers: | |||
| o SHOULD rotate refresh tokens on each use, in order to be able to | o MUST either rotate refresh tokens on each use OR use sender- | |||
| detect a stolen refresh token if one is replayed (described in | constrained refresh tokens as described in [oauth-security-topics] | |||
| [oauth-security-topics] section 4.12) | Section 4.13.2 | |||
| o MUST either set a maximum lifetime on refresh tokens OR expire if | o MUST either set a maximum lifetime on refresh tokens OR expire if | |||
| the refresh token has not been used within some amount of time | the refresh token has not been used within some amount of time | |||
| o MUST NOT extend the lifetime of the new refresh token beyond the | ||||
| lifetime of the initial refresh token | ||||
| o upon issuing a rotated refresh token, MUST NOT extend the lifetime | o upon issuing a rotated refresh token, MUST NOT extend the lifetime | |||
| of the new refresh token beyond the lifetime of the initial | of the new refresh token beyond the lifetime of the initial | |||
| refresh token if the refresh token has a preestablished expiration | refresh token if the refresh token has a preestablished expiration | |||
| time | time | |||
| For example: | For example: | |||
| o A user authorizes an application, issuing an access token that | o A user authorizes an application, issuing an access token that | |||
| lasts 1 hour, and a refresh token that lasts 24 hours | lasts 1 hour, and a refresh token that lasts 24 hours | |||
| skipping to change at page 11, line 25 ¶ | skipping to change at page 11, line 29 ¶ | |||
| o At this point, when the application attempts to use the refresh | o At this point, when the application attempts to use the refresh | |||
| token after 24 hours, the request will fail and the application | token after 24 hours, the request will fail and the application | |||
| will have to involve the user in a new authorization request | will have to involve the user in a new authorization request | |||
| By limiting the overall refresh token lifetime to the lifetime of the | By limiting the overall refresh token lifetime to the lifetime of the | |||
| initial refresh token, this ensures a stolen refresh token cannot be | initial refresh token, this ensures a stolen refresh token cannot be | |||
| used indefinitely. | used indefinitely. | |||
| Authorization servers MAY set different policies around refresh token | Authorization servers MAY set different policies around refresh token | |||
| issuance, lifetime and expiration for browser-based apps compared to | issuance, lifetime and expiration for browser-based applications | |||
| other public clients. | compared to other public clients. | |||
| 9. Security Considerations | 9. Security Considerations | |||
| 9.1. Registration of Browser-Based Apps | 9.1. Registration of Browser-Based Apps | |||
| Browser-based applications are considered public clients as defined | Browser-based applications are considered public clients as defined | |||
| by section 2.1 of OAuth 2.0 [RFC6749], and MUST be registered with | by Section 2.1 of OAuth 2.0 [RFC6749], and MUST be registered with | |||
| the authorization server as such. Authorization servers MUST record | the authorization server as such. Authorization servers MUST record | |||
| the client type in the client registration details in order to | the client type in the client registration details in order to | |||
| identify and process requests accordingly. | identify and process requests accordingly. | |||
| Authorization servers MUST require that browser-based applications | Authorization servers MUST require that browser-based applications | |||
| register one or more redirect URIs. | register one or more redirect URIs. | |||
| 9.2. Client Authentication | 9.2. Client Authentication | |||
| Since a browser-based application's source code is delivered to the | Since a browser-based application's source code is delivered to the | |||
| skipping to change at page 12, line 43 ¶ | skipping to change at page 12, line 49 ¶ | |||
| ensuring the authorization server supports PKCE and relying on the | ensuring the authorization server supports PKCE and relying on the | |||
| CSRF protection that PKCE provides, or if the client is also an | CSRF protection that PKCE provides, or if the client is also an | |||
| OpenID Connect client, using the OpenID Connect "nonce" parameter, or | OpenID Connect client, using the OpenID Connect "nonce" parameter, or | |||
| by using the "state" parameter to carry one-time-use CSRF tokens as | by using the "state" parameter to carry one-time-use CSRF tokens as | |||
| described in Section 7.1. | described in Section 7.1. | |||
| See Section 2.1 of [oauth-security-topics] for additional details. | See Section 2.1 of [oauth-security-topics] for additional details. | |||
| 9.5. Authorization Server Mix-Up Mitigation | 9.5. Authorization Server Mix-Up Mitigation | |||
| The security considerations around the authorization server mix-up | Authorization server mix-up attacks mark a severe threat to every | |||
| that are referenced in Section 8.10 of [RFC8252] also apply to | client that supports at least two authorization servers. To conform | |||
| browser-based apps. | to this BCP such clients MUST apply countermeasures to defend against | |||
| mix-up attacks. | ||||
| Clients MUST use a unique redirect URI for each authorization server | It is RECOMMENDED to defend against mix-up attacks by identifying and | |||
| used by the application. The client MUST store the redirect URI | validating the issuer of the authorization response. This can be | |||
| along with the session data (e.g. along with "state") and MUST verify | achieved either by using the "iss" response parameter, as defined in | |||
| that the URI on which the authorization response was received exactly | [oauth-iss-auth-resp], or by using the "iss" Claim of the ID token | |||
| matches. | when OpenID Connect is used. | |||
| Alternative countermeasures, such as using distinct redirect URIs for | ||||
| each issuer, SHOULD only be used if identifying the issuer as | ||||
| described is not possible. | ||||
| Section 4.4 of [oauth-security-topics] provides additional details | ||||
| about mix-up attacks and the countermeasures mentioned above. | ||||
| 9.6. Cross-Domain Requests | 9.6. Cross-Domain Requests | |||
| To complete the authorization code flow, the browser-based | To complete the Authorization Code flow, the browser-based | |||
| application will need to exchange the authorization code for an | application will need to exchange the authorization code for an | |||
| access token at the token endpoint. If the authorization server | access token at the token endpoint. If the authorization server | |||
| provides additional endpoints to the application, such as metadata | provides additional endpoints to the application, such as metadata | |||
| URLs, dynamic client registration, revocation, introspection, | URLs, dynamic client registration, revocation, introspection, | |||
| discovery or user info endpoints, these endpoints may also be | discovery or user info endpoints, these endpoints may also be | |||
| accessed by the browser-based app. Since these requests will be made | accessed by the browser-based app. Since these requests will be made | |||
| from a browser, authorization servers MUST support the necessary CORS | from a browser, authorization servers MUST support the necessary CORS | |||
| headers (defined in [Fetch]) to allow the browser to make the | headers (defined in [Fetch]) to allow the browser to make the | |||
| request. | request. | |||
| This specification does not include guidelines for deciding whether a | This specification does not include guidelines for deciding whether a | |||
| CORS policy for the token endpoint should be a wildcard origin or | CORS policy for the token endpoint should be a wildcard origin or | |||
| more restrictive. Note, however, that the browser will attempt to | more restrictive. Note, however, that the browser will attempt to | |||
| GET or POST to the API endpoint before knowing any CORS policy; it | GET or POST to the API endpoint before knowing any CORS policy; it | |||
| simply hides the succeeding or failing result from JavaScript if the | simply hides the succeeding or failing result from JavaScript if the | |||
| policy does not allow sharing. | policy does not allow sharing. | |||
| 9.7. Content-Security Policy | 9.7. Content Security Policy | |||
| A browser-based application that wishes to use either long-lived | A browser-based application that wishes to use either long-lived | |||
| refresh tokens or privileged scopes SHOULD restrict its JavaScript | refresh tokens or privileged scopes SHOULD restrict its JavaScript | |||
| execution to a set of statically hosted scripts via a Content | execution to a set of statically hosted scripts via a Content | |||
| Security Policy ([CSP2]) or similar mechanism. A strong Content | Security Policy ([CSP2]) or similar mechanism. A strong Content | |||
| Security Policy can limit the potential attack vectors for malicious | Security Policy can limit the potential attack vectors for malicious | |||
| JavaScript to be executed on the page. | JavaScript to be executed on the page. | |||
| 9.8. OAuth Implicit Flow | 9.8. OAuth Implicit Flow | |||
| The OAuth 2.0 Implicit flow (defined in Section 4.2 of OAuth 2.0 | The OAuth 2.0 Implicit flow (defined in Section 4.2 of OAuth 2.0 | |||
| [RFC6749]) works by the authorization server issuing an access token | [RFC6749]) works by the authorization server issuing an access token | |||
| in the authorization response (front-channel) without the code | in the authorization response (front channel) without the code | |||
| exchange step. In this case, the access token is returned in the | exchange step. In this case, the access token is returned in the | |||
| fragment part of the redirect URI, providing an attacker with several | fragment part of the redirect URI, providing an attacker with several | |||
| opportunities to intercept and steal the access token. | opportunities to intercept and steal the access token. | |||
| Authorization servers MUST NOT issue access tokens in the | Authorization servers MUST NOT issue access tokens in the | |||
| authorization response, and MUST issue access tokens only from the | authorization response, and MUST issue access tokens only from the | |||
| token endpoint. | token endpoint. | |||
| 9.8.1. Attacks on the Implicit Flow | 9.8.1. Attacks on the Implicit Flow | |||
| Many attacks on the implicit flow described by [RFC6819] and | Many attacks on the Implicit flow described by [RFC6819] and | |||
| [oauth-security-topics] do not have sufficient mitigation strategies. | Section 4.1.2 of [oauth-security-topics] do not have sufficient | |||
| The following sections describe the specific attacks that cannot be | mitigation strategies. The following sections describe the specific | |||
| mitigated while continuing to use the implicit flow. | attacks that cannot be mitigated while continuing to use the Implicit | |||
| flow. | ||||
| 9.8.1.1. Threat: Interception of the Redirect URI | 9.8.1.1. Threat: Manipulation of the Redirect URI | |||
| If an attacker is able to cause the authorization response to be sent | If an attacker is able to cause the authorization response to be sent | |||
| to a URI under their control, they will directly get access to the | to a URI under their control, they will directly get access to the | |||
| authorization response including the access token. Several methods | authorization response including the access token. Several methods | |||
| of performing this attack are described in detail in | of performing this attack are described in detail in | |||
| [oauth-security-topics]. | [oauth-security-topics]. | |||
| 9.8.1.2. Threat: Access Token Leak in Browser History | 9.8.1.2. Threat: Access Token Leak in Browser History | |||
| An attacker could obtain the access token from the browser's history. | An attacker could obtain the access token from the browser's history. | |||
| skipping to change at page 14, line 32 ¶ | skipping to change at page 14, line 46 ¶ | |||
| services and to multiple devices, providing an even wider attack | services and to multiple devices, providing an even wider attack | |||
| surface to extract access tokens out of the URL. | surface to extract access tokens out of the URL. | |||
| This is discussed in more detail in Section 4.3.2 of | This is discussed in more detail in Section 4.3.2 of | |||
| [oauth-security-topics]. | [oauth-security-topics]. | |||
| 9.8.1.3. Threat: Manipulation of Scripts | 9.8.1.3. Threat: Manipulation of Scripts | |||
| An attacker could modify the page or inject scripts into the browser | An attacker could modify the page or inject scripts into the browser | |||
| through various means, including when the browser's HTTPS connection | through various means, including when the browser's HTTPS connection | |||
| is being man-in-the-middled by, for example, a corporate network. | is being intercepted by, for example, a corporate network. While | |||
| While this type of attack is typically out of scope of basic security | man-in-the-middle attacks are typically out of scope of basic | |||
| recommendations to prevent, in the case of browser-based apps it is | security recommendations to prevent, in the case of browser-based | |||
| much easier to perform this kind of attack, where an injected script | apps they are much easier to perform. An injected script can enable | |||
| can suddenly have access to everything on the page. | an attacker to have access to everything on the page. | |||
| The risk of a malicious script running on the page may be amplified | The risk of a malicious script running on the page may be amplified | |||
| when the application uses a known standard way of obtaining access | when the application uses a known standard way of obtaining access | |||
| tokens, namely that the attacker can always look at the | tokens, namely that the attacker can always look at the | |||
| "window.location" variable to find an access token. This threat | "window.location" variable to find an access token. This threat | |||
| profile is different from an attacker specifically targeting an | profile is different from an attacker specifically targeting an | |||
| individual application by knowing where or how an access token | individual application by knowing where or how an access token | |||
| obtained via the authorization code flow may end up being stored. | obtained via the Authorization Code flow may end up being stored. | |||
| 9.8.1.4. Threat: Access Token Leak to Third Party Scripts | 9.8.1.4. Threat: Access Token Leak to Third-Party Scripts | |||
| It is relatively common to use third-party scripts in browser-based | It is relatively common to use third-party scripts in browser-based | |||
| apps, such as analytics tools, crash reporting, and even things like | apps, such as analytics tools, crash reporting, and even things like | |||
| a Facebook or Twitter "like" button. In these situations, the author | a Facebook or Twitter "like" button. In these situations, the author | |||
| of the application may not be able to be fully aware of the entirety | of the application may not be able to be fully aware of the entirety | |||
| of the code running in the application. When an access token is | of the code running in the application. When an access token is | |||
| returned in the fragment, it is visible to any third-party scripts on | returned in the fragment, it is visible to any third-party scripts on | |||
| the page. | the page. | |||
| 9.8.2. Countermeasures | 9.8.2. Countermeasures | |||
| In addition to the countermeasures described by [RFC6819] and | In addition to the countermeasures described by [RFC6819] and | |||
| [oauth-security-topics], using the authorization code with PKCE | [oauth-security-topics], using the Authorization Code flow with PKCE | |||
| extension prevents the attacks described above by avoiding returning | extension prevents the attacks described above by avoiding returning | |||
| the access token in the redirect response at all. | the access token in the redirect response at all. | |||
| When PKCE is used, if an authorization code is stolen in transport, | When PKCE is used, if an authorization code is stolen in transport, | |||
| the attacker is unable to do anything with the authorization code. | the attacker is unable to do anything with the authorization code. | |||
| 9.8.3. Disadvantages of the Implicit Flow | 9.8.3. Disadvantages of the Implicit Flow | |||
| There are several additional reasons the Implicit flow is | There are several additional reasons the Implicit flow is | |||
| disadvantageous compared to using the standard Authorization Code | disadvantageous compared to using the standard Authorization Code | |||
| skipping to change at page 15, line 34 ¶ | skipping to change at page 15, line 50 ¶ | |||
| particular access token was intended for that client, which could | particular access token was intended for that client, which could | |||
| lead to misuse and possible impersonation attacks if a malicious | lead to misuse and possible impersonation attacks if a malicious | |||
| party hands off an access token it retrieved through some other | party hands off an access token it retrieved through some other | |||
| means to the client. | means to the client. | |||
| o Returning an access token in the front-channel redirect gives the | o Returning an access token in the front-channel redirect gives the | |||
| authorization server no assurance that the access token will | authorization server no assurance that the access token will | |||
| actually end up at the application, since there are many ways this | actually end up at the application, since there are many ways this | |||
| redirect may fail or be intercepted. | redirect may fail or be intercepted. | |||
| o Supporting the implicit flow requires additional code, more upkeep | o Supporting the Implicit flow requires additional code, more upkeep | |||
| and understanding of the related security considerations, while | and understanding of the related security considerations, while | |||
| limiting the authorization server to just the authorization code | limiting the authorization server to just the Authorization Code | |||
| flow reduces the attack surface of the implementation. | flow reduces the attack surface of the implementation. | |||
| o If the JavaScript application gets wrapped into a native app, then | o If the JavaScript application gets wrapped into a native app, then | |||
| [RFC8252] also requires the use of the authorization code flow | [RFC8252] also requires the use of the Authorization Code flow | |||
| with PKCE anyway. | with PKCE anyway. | |||
| In OpenID Connect, the id_token is sent in a known format (as a JWT), | In OpenID Connect, the id_token is sent in a known format (as a JWT), | |||
| and digitally signed. Returning an id_token using the Implicit flow | and digitally signed. Returning an id_token using the Implicit flow | |||
| ("response_type=id_token") requires the client validate the JWT | ("response_type=id_token") requires the client validate the JWT | |||
| signature, as malicious parties could otherwise craft and supply | signature, as malicious parties could otherwise craft and supply | |||
| fraudulent id_tokens. Performing OpenID Connect using the | fraudulent id_tokens. Performing OpenID Connect using the | |||
| authorization code flow provides the benefit of the client not | Authorization Code flow provides the benefit of the client not | |||
| needing to verify the JWT signature, as the ID token will have been | needing to verify the JWT signature, as the ID token will have been | |||
| fetched over an HTTPS connection directly from the authorization | fetched over an HTTPS connection directly from the authorization | |||
| server. Additionally, in many cases an application will request both | server. Additionally, in many cases an application will request both | |||
| an ID token and an access token, so it is simplier and provides fewer | an ID token and an access token, so it is simplier and provides fewer | |||
| attack vectors to obtain both via the authorization code flow. | attack vectors to obtain both via the Authorization Code flow. | |||
| 9.8.4. Historic Note | 9.8.4. Historic Note | |||
| Historically, the Implicit flow provided an advantage to single-page | Historically, the Implicit flow provided an advantage to browser- | |||
| apps since JavaScript could always arbitrarily read and manipulate | based apps since JavaScript could always arbitrarily read and | |||
| the fragment portion of the URL without triggering a page reload. | manipulate the fragment portion of the URL without triggering a page | |||
| This was necessary in order to remove the access token from the URL | reload. This was necessary in order to remove the access token from | |||
| after it was obtained by the app. | the URL after it was obtained by the app. | |||
| Modern browsers now have the Session History API (described in | Modern browsers now have the Session History API (described in | |||
| "Session history and navigation" of [HTML]), which provides a | "Session history and navigation" of [HTML]), which provides a | |||
| mechanism to modify the path and query string component of the URL | mechanism to modify the path and query string component of the URL | |||
| without triggering a page reload. This means modern browser-based | without triggering a page reload. This means modern browser-based | |||
| apps can use the unmodified OAuth 2.0 authorization code flow, since | apps can use the unmodified OAuth 2.0 Authorization Code flow, since | |||
| they have the ability to remove the authorization code from the query | they have the ability to remove the authorization code from the query | |||
| string without triggering a page reload thanks to the Session History | string without triggering a page reload thanks to the Session History | |||
| API. | API. | |||
| 9.9. Additional Security Considerations | 9.9. Additional Security Considerations | |||
| The OWASP Foundation (https://www.owasp.org/) maintains a set of | The OWASP Foundation (https://www.owasp.org/) maintains a set of | |||
| security recommendations and best practices for web applications, and | security recommendations and best practices for web applications, and | |||
| it is RECOMMENDED to follow these best practices when creating an | it is RECOMMENDED to follow these best practices when creating an | |||
| OAuth 2.0 Browser-Based application. | OAuth 2.0 Browser-Based application. | |||
| skipping to change at page 16, line 43 ¶ | skipping to change at page 17, line 13 ¶ | |||
| This document does not require any IANA actions. | This document does not require any IANA actions. | |||
| 11. References | 11. References | |||
| 11.1. Normative References | 11.1. Normative References | |||
| [CSP2] West, M., "Content Security Policy", October 2018. | [CSP2] West, M., "Content Security Policy", October 2018. | |||
| [Fetch] whatwg, "Fetch", 2018. | [Fetch] whatwg, "Fetch", 2018. | |||
| [oauth-iss-auth-resp] | ||||
| Meyer zu Selhausen, K. and D. Fett, "OAuth 2.0 | ||||
| Authorization Server Issuer Identifier in Authorization | ||||
| Response", January 2021. | ||||
| [oauth-security-topics] | [oauth-security-topics] | |||
| Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, | Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, | |||
| "OAuth 2.0 Security Best Current Practice", July 2019. | "OAuth 2.0 Security Best Current Practice", April 2021. | |||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
| DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
| <https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
| [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", | [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", | |||
| RFC 6749, DOI 10.17487/RFC6749, October 2012, | RFC 6749, DOI 10.17487/RFC6749, October 2012, | |||
| <https://www.rfc-editor.org/info/rfc6749>. | <https://www.rfc-editor.org/info/rfc6749>. | |||
| skipping to change at page 18, line 13 ¶ | skipping to change at page 18, line 38 ¶ | |||
| clients. | clients. | |||
| 7. Follow the [oauth-security-topics] recommendations on refresh | 7. Follow the [oauth-security-topics] recommendations on refresh | |||
| tokens, as well as the additional requirements described in | tokens, as well as the additional requirements described in | |||
| Section 8. | Section 8. | |||
| Appendix B. Document History | Appendix B. Document History | |||
| [[ To be removed from the final specification ]] | [[ To be removed from the final specification ]] | |||
| -08 | ||||
| o Added a note to use the "Secure" cookie attribute in addition to | ||||
| SameSite etc | ||||
| o Updates to bring this draft in sync with the latest Security BCP | ||||
| o Updated text for mix-up countermeasures to reference the new "iss" | ||||
| extension | ||||
| o Changed "SHOULD" for refresh token rotation to MUST either use | ||||
| rotation or sender-constraining to match the Security BCP | ||||
| o Fixed references to other specs and extensions | ||||
| o Editorial improvements in descriptions of the different | ||||
| architectures | ||||
| -07 | -07 | |||
| o Clarify PKCE requirements apply only to issuing access tokens | o Clarify PKCE requirements apply only to issuing access tokens | |||
| o Change "MUST" to "SHOULD" for refresh token rotation | o Change "MUST" to "SHOULD" for refresh token rotation | |||
| o Editorial clarifications | o Editorial clarifications | |||
| -06 | -06 | |||
| skipping to change at page 19, line 48 ¶ | skipping to change at page 20, line 43 ¶ | |||
| -02 | -02 | |||
| o Rewrote overview section incorporating feedback from Leo Tohill | o Rewrote overview section incorporating feedback from Leo Tohill | |||
| o Updated summary recommendation bullet points to split out | o Updated summary recommendation bullet points to split out | |||
| application and server requirements | application and server requirements | |||
| o Removed the allowance on hostname-only redirect URI matching, now | o Removed the allowance on hostname-only redirect URI matching, now | |||
| requiring exact redirect URI matching | requiring exact redirect URI matching | |||
| o Updated section 6.2 to drop reference of SPA with a backend | o Updated Section 6.2 to drop reference of SPA with a backend | |||
| component being a public client | component being a public client | |||
| o Expanded the architecture section to explicitly mention three | o Expanded the architecture section to explicitly mention three | |||
| architectural patterns available to JS apps | architectural patterns available to JS apps | |||
| -01 | -01 | |||
| o Incorporated feedback from Torsten Lodderstedt | o Incorporated feedback from Torsten Lodderstedt | |||
| o Updated abstract | o Updated abstract | |||
| o Clarified the definition of browser-based apps to not exclude | o Clarified the definition of browser-based apps to not exclude | |||
| applications cached in the browser, e.g. via Service Workers | applications cached in the browser, e.g. via Service Workers | |||
| o Clarified use of the state parameter for CSRF protection | o Clarified use of the state parameter for CSRF protection | |||
| o Added background information about the original reason the | o Added background information about the original reason the | |||
| implicit flow was created due to lack of CORS support | implicit flow was created due to lack of CORS support | |||
| skipping to change at page 20, line 40 ¶ | skipping to change at page 21, line 32 ¶ | |||
| John Bradley, whose recommendation for native apps informed many of | John Bradley, whose recommendation for native apps informed many of | |||
| the best practices for browser-based applications. The authors would | the best practices for browser-based applications. The authors would | |||
| also like to thank Hannes Tschofenig and Torsten Lodderstedt, the | also like to thank Hannes Tschofenig and Torsten Lodderstedt, the | |||
| attendees of the Internet Identity Workshop 27 session at which this | attendees of the Internet Identity Workshop 27 session at which this | |||
| BCP was originally proposed, and the following individuals who | BCP was originally proposed, and the following individuals who | |||
| contributed ideas, feedback, and wording that shaped and formed the | contributed ideas, feedback, and wording that shaped and formed the | |||
| final specification: | final specification: | |||
| Annabelle Backman, Brian Campbell, Brock Allen, Christian Mainka, | Annabelle Backman, Brian Campbell, Brock Allen, Christian Mainka, | |||
| Daniel Fett, George Fletcher, Hannes Tschofenig, Janak Amarasena, | Daniel Fett, George Fletcher, Hannes Tschofenig, Janak Amarasena, | |||
| John Bradley, Joseph Heenan, Justin Richer, Karl McGuinness, Leo | John Bradley, Joseph Heenan, Justin Richer, Karl McGuinness, Karsten | |||
| Tohill, Mike Jones, Tomek Stojecki, Torsten Lodderstedt, and Vittorio | Meyer zu Selhausen, Leo Tohill, Mike Jones, Tomek Stojecki, Torsten | |||
| Bertocci. | Lodderstedt, and Vittorio Bertocci. | |||
| Authors' Addresses | Authors' Addresses | |||
| Aaron Parecki | Aaron Parecki | |||
| Okta | Okta | |||
| Email: aaron@parecki.com | Email: aaron@parecki.com | |||
| URI: https://aaronparecki.com | URI: https://aaronparecki.com | |||
| David Waite | David Waite | |||
| Ping Identity | Ping Identity | |||
| Email: david@alkaline-solutions.com | Email: david@alkaline-solutions.com | |||
| End of changes. 68 change blocks. | ||||
| 122 lines changed or deleted | 168 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||