idnits 2.17.1 draft-ietf-oauth-browser-based-apps-02.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (July 08, 2019) is 1748 days in the past. Is this intentional? Checking references for intended status: Best Current Practice ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Possible downref: Non-RFC (?) normative reference: ref. 'CSP2' -- Possible downref: Non-RFC (?) normative reference: ref. 'Fetch' ** Downref: Normative reference to an Informational RFC: RFC 6819 Summary: 1 error (**), 0 flaws (~~), 1 warning (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Open Authentication Protocol A. Parecki 3 Internet-Draft Okta 4 Intended status: Best Current Practice D. Waite 5 Expires: January 9, 2020 Ping Identity 6 July 08, 2019 8 OAuth 2.0 for Browser-Based Apps 9 draft-ietf-oauth-browser-based-apps-02 11 Abstract 13 OAuth 2.0 authorization requests from browser-based apps must be made 14 using the authorization code grant with the PKCE extension, and 15 should not be issued a client secret when registered. 17 This specification details the security considerations that must be 18 taken into account when developing browser-based applications, as 19 well as best practices for how they can securely implement OAuth 2.0. 21 Status of This Memo 23 This Internet-Draft is submitted in full conformance with the 24 provisions of BCP 78 and BCP 79. 26 Internet-Drafts are working documents of the Internet Engineering 27 Task Force (IETF). Note that other groups may also distribute 28 working documents as Internet-Drafts. The list of current Internet- 29 Drafts is at https://datatracker.ietf.org/drafts/current/. 31 Internet-Drafts are draft documents valid for a maximum of six months 32 and may be updated, replaced, or obsoleted by other documents at any 33 time. It is inappropriate to use Internet-Drafts as reference 34 material or to cite them other than as "work in progress." 36 This Internet-Draft will expire on January 9, 2020. 38 Copyright Notice 40 Copyright (c) 2019 IETF Trust and the persons identified as the 41 document authors. All rights reserved. 43 This document is subject to BCP 78 and the IETF Trust's Legal 44 Provisions Relating to IETF Documents 45 (https://trustee.ietf.org/license-info) in effect on the date of 46 publication of this document. Please review these documents 47 carefully, as they describe your rights and restrictions with respect 48 to this document. Code Components extracted from this document must 49 include Simplified BSD License text as described in Section 4.e of 50 the Trust Legal Provisions and are provided without warranty as 51 described in the Simplified BSD License. 53 Table of Contents 55 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 56 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 3 57 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 58 4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 59 5. First-Party Applications . . . . . . . . . . . . . . . . . . 5 60 6. Application Architecture Patterns . . . . . . . . . . . . . . 5 61 6.1. Apps Served from a Common Domain as the Resource Server . 6 62 6.2. Apps Served from a Dynamic Application Server . . . . . . 6 63 6.3. Apps Served from a Static Web Server . . . . . . . . . . 8 64 7. Authorization Code Flow . . . . . . . . . . . . . . . . . . . 9 65 7.1. Initiating the Authorization Request from a Browser-Based 66 Application . . . . . . . . . . . . . . . . . . . . . . . 9 67 7.2. Handling the Authorization Code Redirect . . . . . . . . 9 68 8. Refresh Tokens . . . . . . . . . . . . . . . . . . . . . . . 10 69 9. Security Considerations . . . . . . . . . . . . . . . . . . . 10 70 9.1. Registration of Browser-Based Apps . . . . . . . . . . . 10 71 9.2. Client Authentication . . . . . . . . . . . . . . . . . . 10 72 9.3. Client Impersonation . . . . . . . . . . . . . . . . . . 11 73 9.4. Cross-Site Request Forgery Protections . . . . . . . . . 11 74 9.5. Authorization Server Mix-Up Mitigation . . . . . . . . . 11 75 9.6. Cross-Domain Requests . . . . . . . . . . . . . . . . . . 12 76 9.7. Content-Security Policy . . . . . . . . . . . . . . . . . 12 77 9.8. OAuth Implicit Grant Authorization Flow . . . . . . . . . 12 78 9.8.1. Threat: Interception of the Redirect URI . . . . . . 13 79 9.8.2. Threat: Access Token Leak in Browser History . . . . 13 80 9.8.3. Threat: Manipulation of Scripts . . . . . . . . . . . 13 81 9.8.4. Threat: Access Token Leak to Third Party Scripts . . 13 82 9.8.5. Countermeasures . . . . . . . . . . . . . . . . . . . 14 83 9.8.6. Disadvantages of the Implicit Flow . . . . . . . . . 14 84 9.8.7. Historic Note . . . . . . . . . . . . . . . . . . . . 15 85 9.9. Additional Security Considerations . . . . . . . . . . . 15 86 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 87 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 88 11.1. Normative References . . . . . . . . . . . . . . . . . . 15 89 11.2. Informative References . . . . . . . . . . . . . . . . . 16 90 Appendix A. Server Support Checklist . . . . . . . . . . . . . . 16 91 Appendix B. Document History . . . . . . . . . . . . . . . . . . 16 92 Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 17 93 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 17 95 1. Introduction 97 This specification describes the current best practices for 98 implementing OAuth 2.0 authorization flows in applications running 99 entirely in a browser. 101 For native application developers using OAuth 2.0 and OpenID Connect, 102 an IETF BCP (best current practice) was published that guides 103 integration of these technologies. This document is formally known 104 as [RFC8252] or BCP 212, but nicknamed "AppAuth" after the OpenID 105 Foundation-sponsored set of libraries that assist developers in 106 adopting these practices. 108 AppAuth steers developers away from performing user authorization via 109 embedding user agents such as browser controls into native apps, 110 instead insisting that an external agent (such as the system browser) 111 be used. The RFC continues on to promote capabilities and 112 supplemental specifications beyond the base OAuth 2.0 and OpenID 113 Connect specifications to improve baseline security, such as 114 [RFC7636], also known as PKCE. 116 OAuth 2.0 for Browser-Based Apps addresses the similarities between 117 implementing OAuth for native apps as well as browser-based apps, and 118 includes additional considerations when running in a browser. This 119 is primarily focused on OAuth, except where OpenID Connect provides 120 additional considerations. 122 2. Notational Conventions 124 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 125 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 126 "OPTIONAL" in this document are to be interpreted as described in 127 [RFC2119]. 129 3. Terminology 131 In addition to the terms defined in referenced specifications, this 132 document uses the following terms: 134 "OAuth": In this document, "OAuth" refers to OAuth 2.0, [RFC6749]. 136 "Browser-based application": An application that is dynamically 137 downloaded and executed in a web browser, usually written in 138 JavaScript. Also sometimes referred to as a "single-page 139 application", or "SPA". 141 4. Overview 143 At the time that OAuth 2.0 RFC 6749 was created, browser-based 144 JavaScript applications needed a solution that strictly complied with 145 the same-origin policy. Common deployments of OAuth 2.0 involved an 146 application running on a different domain than the authorization 147 server, so it was historically not possible to use the authorization 148 code flow which would require a cross-origin POST request. This was 149 the principal motivation for the definition of the implicit flow, 150 which returns the access token in the front channel via the fragment 151 part of the URL, bypassing the need for a cross-origin POST request. 153 However, there are several drawbacks to the implicit flow, generally 154 involving vulnerabilities associated with the exposure of the access 155 token in the URL. See Section 9.8 for an analysis of these attacks 156 and the drawbacks of using the implicit flow in browsers. Additional 157 attacks and security considerations can be found in 158 [oauth-security-topics]. 160 In recent years, widespread adoption of Cross-Origin Resource Sharing 161 (CORS), which enables exceptions to the same-origin policy, allows 162 browser-based apps to use the OAuth 2.0 authorization code flow and 163 make a POST request to exchange the authorization code for an access 164 token at the token endpoint. In this flow, the access token is never 165 exposed in the less secure front-channel. Furthermore, adding PKCE 166 to the flow assures that even if an authorization code is 167 intercepted, it is unusable by an attacker. 169 For this reason, and from other lessons learned, the current best 170 practice for browser-based applications is to use the OAuth 2.0 171 authorization code flow with PKCE. 173 Applications should: 175 o Use the OAuth 2.0 authorization code flow with the PKCE extension 177 o Use the OAuth 2.0 state parameter to carry one-time use CSRF 178 tokens 180 o Register one or more redirect URIs, and not vary the redirect URI 181 per authorization request 183 OAuth 2.0 servers should: 185 o Require exact matching of registered redirect URIs 187 5. First-Party Applications 189 While OAuth and OpenID Connect were initially created to allow third- 190 party applications to access an API on behalf of a user, they have 191 both proven to be useful in a first-party scenario as well. First- 192 party apps are applications where by the same organization that 193 provides the API being accessed by the application. 195 For example, a web email client provided by the operator of the email 196 account, or a mobile banking application created by bank itself. 197 (Note that there is no requirement that the application actually be 198 developed by the same company; a mobile banking application developed 199 by a contractor that is branded as the bank's application is still 200 considered a first-party application.) The first-party app 201 consideration is about the user's relationship to the application and 202 the service. 204 To conform to this best practice, first-party applications using 205 OAuth or OpenID Connect MUST use the OAuth Authorization Code flow as 206 described later in this document or use the OAuth Password grant. 208 It is strongly RECOMMENDED that applications use the Authorization 209 Code flow over the Password grant for several reasons. By 210 redirecting to the authorization server, this provides the 211 authorization server the opportunity to prompt the user for multi- 212 factor authentication options, take advantage of single-sign-on 213 sessions, or use third-party identity providers. In contrast, the 214 Password grant does not provide any built-in mechanism for these, and 215 must be extended with custom code. 217 6. Application Architecture Patterns 219 There are three primary architectural patterns available when 220 building browser-based applications. 222 o JavaScript served from a common domain as the resource server 224 o JavaScript served from a dynamic application server 226 o JavaScript served from a static web server 228 These three architectures have different use cases and 229 considerations. 231 6.1. Apps Served from a Common Domain as the Resource Server 233 For simple system architectures, such as when the JavaScript 234 application is served from a domain that can share cookies with the 235 domain of the API (resource server), it is likely a better decision 236 to avoid using OAuth entirely, and just use session authentication to 237 communicate directly with the API. 239 OAuth and OpenID Connect provide very little benefit in this 240 deployment scenario, so it is recommended to reconsider whether you 241 need OAuth or OpenID Connect at all in this case. Session 242 authentication has the benefit of having fewer moving parts and fewer 243 attack vectors. OAuth and OpenID Connect were created primarily for 244 third-party or federated access to APIs, so may not be the best 245 solution in a same-domain scenario. 247 6.2. Apps Served from a Dynamic Application Server 248 +-------------+ 249 | | 250 |Authorization| 251 | Server | 252 | | 253 +-------------+ 255 ^ + 256 |(A) |(B) 257 | | 258 + v 260 +-------------+ +--------------+ 261 | | +---------> | | 262 | Application | (C) | Resource | 263 | Server | | Server | 264 | | <---------+ | | 265 +-------------+ (D) +--------------+ 267 ^ + 268 | | 269 | | browser 270 | | cookie 271 | | 272 + v 274 +-------------+ 275 | | 276 | Browser | 277 | | 278 +-------------+ 280 In this architecture, the JavaScript code is loaded from a dynamic 281 Application Server that also has the ability to execute code itself. 282 This enables the ability to keep all of the steps involved in 283 obtaining an access token outside of the JavaScript application. 285 (Common examples of this architecture are an Angular front-end with a 286 .NET backend, or a React front-end with a Spring Boot backend.) 288 The Application Server SHOULD be considered a confidential client, 289 and issued its own client secret. The Application Server SHOULD use 290 the OAuth 2.0 authorization code grant to initiate a request request 291 for an access token. Upon handling the redirect from the 292 Authorization Server, the Application Server will request an access 293 token using the authorization code returned (A), which will be 294 returned to the Application Server (B). The Application Server 295 utilizes its own session with the browser to store the access token. 297 When the JavaScript application in the browser wants to make a 298 request to the Resource Server, it MUST instead make the request to 299 the Application Server, and the Application Server will make the 300 request with the access token to the Resource Server (C), and forward 301 the response (D) back to the browser. 303 Security of the connection between code running in the browser and 304 this Application Server is assumed to utilize browser-level 305 protection mechanisms. Details are out of scope of this document, 306 but many recommendations can be found at the OWASP Foundation 307 (https://www.owasp.org/), such as setting an HTTP-only and Secure 308 cookie to authenticate the session between the browser and 309 Application Server. 311 In this scenario, the session between the browser and Application 312 Server MAY be either a session cookie provided by the Application 313 Server, OR the access token itself. Note that if the access token is 314 used as the session identifier, this exposes the access token to the 315 end user even if it is not available to the JavaScript application, 316 so some authorization servers may wish to limit the capabilities of 317 these clients to mitigate risk. 319 6.3. Apps Served from a Static Web Server 321 +---------------+ +--------------+ 322 | | | | 323 | Authorization | | Resource | 324 | Server | | Server | 325 | | | | 326 +---------------+ +--------------+ 328 ^ + ^ + 329 | | | | 330 |(B) |(C) |(D) |(E) 331 | | | | 332 | | | | 333 + v + v 335 +-----------------+ +-------------------------------+ 336 | | (A) | | 337 | Static Web Host | +-----> | Browser | 338 | | | | 339 +-----------------+ +-------------------------------+ 341 In this architecture, the JavaScript code is first loaded from a 342 static web host into the browser (A). The application then runs in 343 the browser, and is considered a public client since it has no 344 ability to be issued a client secret. 346 The code in the browser then initiates the authorization code flow 347 with the PKCE extension (described in Section 7) (B) above, and 348 obtains an access token via a POST request (C). The JavaScript app 349 is then responsible for storing the access token securely using 350 appropriate browser APIs. 352 When the JavaScript application in the browser wants to make a 353 request to the Resource Server, it can include the access token in 354 the request (D) and make the request directly. 356 In this scenario, the Authorization Server and Resource Server MUST 357 support the necessary CORS headers to enable the JavaScript code to 358 make this POST request from the domain on which the script is 359 executing. (See Section 9.6 for additional details.) 361 7. Authorization Code Flow 363 Public browser-based apps needing user authorization create an 364 authorization request URI with the authorization code grant type per 365 Section 4.1 of OAuth 2.0 [RFC6749], using a redirect URI capable of 366 being received by the app. 368 7.1. Initiating the Authorization Request from a Browser-Based 369 Application 371 Public browser-based apps MUST implement the Proof Key for Code 372 Exchange (PKCE [RFC7636]) extension to OAuth, and authorization 373 servers MUST support PKCE for such clients. 375 The PKCE extension prevents an attack where the authorization code is 376 intercepted and exchanged for an access token by a malicious client, 377 by providing the authorization server with a way to verify the same 378 client instance that exchanges the authorization code is the same one 379 that initiated the flow. 381 Browser-based apps MUST use the OAuth 2.0 "state" parameter to 382 protect themselves against Cross-Site Request Forgery and 383 authorization code swap attacks and MUST use a unique value for each 384 authorization request, and MUST verify the returned state in the 385 authorization response matches the original state the app created. 387 7.2. Handling the Authorization Code Redirect 389 Authorization servers MUST require an exact match of a registered 390 redirect URI. 392 8. Refresh Tokens 394 Refresh tokens provide a way for applications to obtain a new access 395 token when the initial access token expires. [oauth-security-topics] 396 describes some additional requirements around refresh tokens on top 397 of the recommendations of [RFC6749]. 399 For public clients, the risk of a leaked refresh token is much 400 greater than leaked access tokens, since an attacker can potentially 401 continue using the stoken refresh token to obtain new access without 402 being detectable by the authorization server. Additionally, browser- 403 based applications provide many attack vectors by which a refresh 404 token can be leaked. As such, these applications are considered a 405 higher risk for handling refresh tokens. 407 Authorization servers SHOULD NOT issue refresh tokens to browser- 408 based applications. 410 If an authorization server does choose to issue refresh tokens to 411 browser-based applications, then it MUST issue a new refresh token 412 with every access token refresh response. Doing this mitigates the 413 risk of a leaked refresh token, as a leaked refresh token can be 414 detected if both the attacker and the legitimate client attempt to 415 use the same refresh token. Authorization servers MUST follow the 416 additional refresh token replay mitigation techniques described in 417 [oauth-security-topics]. 419 9. Security Considerations 421 9.1. Registration of Browser-Based Apps 423 Browser-based applications are considered public clients as defined 424 by section 2.1 of OAuth 2.0 [RFC6749], and MUST be registered with 425 the authorization server as such. Authorization servers MUST record 426 the client type in the client registration details in order to 427 identify and process requests accordingly. 429 Authorization servers MUST require that browser-based applications 430 register one or more redirect URIs. 432 9.2. Client Authentication 434 Since a browser-based application's source code is delivered to the 435 end-user's browser, it cannot contain provisioned secrets. As such, 436 a browser-based app with native OAuth support is considered a public 437 client as defined by Section 2.1 of OAuth 2.0 [RFC6749]. 439 Secrets that are statically included as part of an app distributed to 440 multiple users should not be treated as confidential secrets, as one 441 user may inspect their copy and learn the shared secret. For this 442 reason, and those stated in Section 5.3.1 of [RFC6819], it is NOT 443 RECOMMENDED for authorization servers to require client 444 authentication of browser-based applications using a shared secret, 445 as this serves little value beyond client identification which is 446 already provided by the client_id request parameter. 448 Authorization servers that still require a statically included shared 449 secret for SPA clients MUST treat the client as a public client, and 450 not accept the secret as proof of the client's identity. Without 451 additional measures, such clients are subject to client impersonation 452 (see Section 9.3 below). 454 9.3. Client Impersonation 456 As stated in Section 10.2 of OAuth 2.0 [RFC6749], the authorization 457 server SHOULD NOT process authorization requests automatically 458 without user consent or interaction, except when the identity of the 459 client can be assured. Even when the user has previously approved an 460 authorization request for a given client_id, the request SHOULD be 461 processed as if no previous request had been approved, unless the 462 identity of the client can be proven. 464 If authorization servers restrict redirect URIs to a fixed set of 465 absolute HTTPS URIs without wildcard domains, paths, or query string 466 components, this exact match of registered absolute HTTPS URIs MAY be 467 accepted by authorization servers as proof of identity of the client 468 for the purpose of deciding whether to automatically process an 469 authorization request when a previous request for the client_id has 470 already been approved. 472 9.4. Cross-Site Request Forgery Protections 474 Section 5.3.5 of [RFC6819] recommends using the "state" parameter to 475 link client requests and responses to prevent CSRF (Cross-Site 476 Request Forgery) attacks. To conform to this best practice, use of 477 the "state" parameter is REQUIRED, as described in Section 7.1. 479 9.5. Authorization Server Mix-Up Mitigation 481 The security considerations around the authorization server mix-up 482 that are referenced in Section 8.10 of [RFC8252] also apply to 483 browser-based apps. 485 Clients MUST use a unique redirect URI for each authorization server 486 used by the application. The client MUST store the redirect URI 487 along with the session data (e.g. along with "state") and MUST verify 488 that the URI on which the authorization response was received exactly 489 matches. 491 9.6. Cross-Domain Requests 493 To complete the authorization code flow, the browser-based 494 application will need to exchange the authorization code for an 495 access token at the token endpoint. If the authorization server 496 provides additional endpoints to the application, such as metadata 497 URLs, dynamic client registration, revocation, introspection, 498 discovery or user info endpoints, these endpoints may also be 499 accessed by the browser-based app. Since these requests will be made 500 from a browser, authorization servers MUST support the necessary CORS 501 headers (defined in [Fetch]) to allow the browser to make the 502 request. 504 This specification does not include guidelines for deciding whether a 505 CORS policy for the token endpoint should be a wildcard origin or 506 more restrictive. Note, however, that the browser will attempt to 507 GET or POST to the API endpoint before knowing any CORS policy; it 508 simply hides the succeeding or failing result from JavaScript if the 509 policy does not allow sharing. If POSTs in particular from 510 unsupported single-page applications are to be rejected as errors per 511 authorization server security policy, such rejection is typically 512 done based on the Origin request header. 514 9.7. Content-Security Policy 516 A browser-based application that wishes to use either long-lived 517 refresh tokens or privileged scopes SHOULD restrict its JavaScript 518 execution to a set of statically hosted scripts via a Content 519 Security Policy ([CSP2]) or similar mechanism. A strong Content 520 Security Policy can limit the potential attack vectors for malicious 521 JavaScript to be executed on the page. 523 9.8. OAuth Implicit Grant Authorization Flow 525 The OAuth 2.0 Implicit grant authorization flow (defined in 526 Section 4.2 of OAuth 2.0 [RFC6749]) works by receiving an access 527 token in the HTTP redirect (front-channel) immediately without the 528 code exchange step. In this case, the access token is returned in 529 the fragment part of the redirect URI, providing an attacker with 530 several opportunities to intercept and steal the access token. 531 Several attacks on the implicit flow are described by [RFC6819] and 532 [oauth-security-topics], not all of which have sufficient mitigation 533 strategies. 535 9.8.1. Threat: Interception of the Redirect URI 537 If an attacker is able to cause the authorization response to be sent 538 to a URI under his control, he will directly get access to the 539 fragment carrying the access token. A method of performing this 540 attack is described in detail in [oauth-security-topics]. 542 9.8.2. Threat: Access Token Leak in Browser History 544 An attacker could obtain the access token from the browser's history. 545 The countermeasures recommended by [RFC6819] are limited to using 546 short expiration times for tokens, and indicating that browsers 547 should not cache the response. Neither of these fully prevent this 548 attack, they only reduce the potential damage. 550 Additionally, many browsers now also sync browser history to cloud 551 services and to multiple devices, providing an even wider attack 552 surface to extract access tokens out of the URL. 554 9.8.3. Threat: Manipulation of Scripts 556 An attacker could modify the page or inject scripts into the browser 557 via various means, including when the browser's HTTPS connection is 558 being man-in-the-middled by for example a corporate network. While 559 this type of attack is typically out of scope of basic security 560 recommendations to prevent, in the case of browser-based apps it is 561 much easier to perform this kind of attack, where an injected script 562 can suddenly have access to everything on the page. 564 The risk of a malicious script running on the page is far greater 565 when the application uses a known standard way of obtaining access 566 tokens, namely that the attacker can always look at the 567 window.location to find an access token. This threat profile is very 568 different compared to an attacker specifically targeting an 569 individual application by knowing where or how an access token 570 obtained via the authorization code flow may end up being stored. 572 9.8.4. Threat: Access Token Leak to Third Party Scripts 574 It is relatively common to use third-party scripts in browser-based 575 apps, such as analytics tools, crash reporting, and even things like 576 a Facebook or Twitter "like" button. In these situations, the author 577 of the application may not be able to be fully aware of the entirety 578 of the code running in the application. When an access token is 579 returned in the fragment, it is visible to any third-party scripts on 580 the page. 582 9.8.5. Countermeasures 584 In addition to the countermeasures described by [RFC6819] and 585 [oauth-security-topics], using the authorization code with PKCE 586 avoids these attacks. 588 When PKCE is used, if an authorization code is stolen in transport, 589 the attacker is unable to do anything with the authorization code. 591 9.8.6. Disadvantages of the Implicit Flow 593 There are several additional reasons the Implicit flow is 594 disadvantageous compared to using the standard Authorization Code 595 flow. 597 o OAuth 2.0 provides no mechanism for a client to verify that an 598 access token was issued to it, which could lead to misuse and 599 possible impersonation attacks if a malicious party hands off an 600 access token it retrieved through some other means to the client. 602 o Returning an access token in the front channel redirect gives the 603 authorization server little assurance that the access token will 604 actually end up at the application, since there are many ways this 605 redirect may fail or be intercepted. 607 o Supporting the implicit flow requires additional code, more upkeep 608 and understanding of the related security considerations, while 609 limiting the authorization server to just the authorization code 610 flow reduces the attack surface of the implementation. 612 o If the JavaScript application gets wrapped into a native app, then 613 [RFC8252] also requires the use of the authorization code flow 614 with PKCE anyway. 616 In OpenID Connect, the id_token is sent in a known format (as a JWT), 617 and digitally signed. Performing OpenID Connect using the 618 authorization code flow also provides the additional benefit of the 619 client not needing to verify the JWT signature, as the token will 620 have been fetched over an HTTPS connection directly from the 621 authorization server. However, returning an id_token using the 622 Implicit flow requires the client validate the JWT signature, as 623 malicious parties could otherwise craft and supply fraudulent 624 id_tokens. 626 9.8.7. Historic Note 628 Historically, the Implicit flow provided an advantage to single-page 629 apps since JavaScript could always arbitrarily read and manipulate 630 the fragment portion of the URL without triggering a page reload. 631 Now with the Session History API (described in "Session history and 632 navigation" of [HTML]), browsers have a mechanism to modify the path 633 component of the URL without triggering a page reload, so this 634 overloaded use of the fragment portion is no longer needed. 636 9.9. Additional Security Considerations 638 The OWASP Foundation (https://www.owasp.org/) maintains a set of 639 security recommendations and best practices for web applications, and 640 it is RECOMMENDED to follow these best practices when creating an 641 OAuth 2.0 Browser-Based application. 643 10. IANA Considerations 645 This document does not require any IANA actions. 647 11. References 649 11.1. Normative References 651 [CSP2] West, M., Barth, A., and D. Veditz, "Content Security 652 Policy", December 2016. 654 [Fetch] whatwg, "Fetch", 2018. 656 [oauth-security-topics] 657 Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, 658 "OAuth 2.0 Security Best Current Practice", November 2018. 660 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 661 Requirement Levels", BCP 14, RFC 2119, 662 DOI 10.17487/RFC2119, March 1997, 663 . 665 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 666 RFC 6749, DOI 10.17487/RFC6749, October 2012, 667 . 669 [RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 670 Threat Model and Security Considerations", RFC 6819, 671 DOI 10.17487/RFC6819, January 2013, 672 . 674 [RFC7636] Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key 675 for Code Exchange by OAuth Public Clients", RFC 7636, 676 DOI 10.17487/RFC7636, September 2015, 677 . 679 [RFC8252] Denniss, W. and J. Bradley, "OAuth 2.0 for Native Apps", 680 BCP 212, RFC 8252, DOI 10.17487/RFC8252, October 2017, 681 . 683 11.2. Informative References 685 [HTML] whatwg, "HTML", 2018. 687 Appendix A. Server Support Checklist 689 OAuth servers that support browser-based apps MUST: 691 1. Require "https" scheme redirect URIs. 693 2. Require exact matching of registered redirect URIs. 695 3. Support PKCE [RFC7636]. Required to protect authorization code 696 grants sent to public clients. See Section 7.1 698 4. Support cross-domain requests at the token endpoint in order to 699 allow browsers to make the authorization code exchange request. 700 See Section 9.6 702 5. Not assume that browser-based clients can keep a secret, and 703 SHOULD NOT issue secrets to applications of this type. 705 Appendix B. Document History 707 [[ To be removed from the final specification ]] 709 -02 711 o Rewrote overview section incorporating feedback from Leo Tohill 713 o Updated summary recommendation bullet points to split out 714 application and server requirements 716 o Removed the allowance on hostname-only redirect URI matching, now 717 requiring exact redirect URI matching 719 o Updated section 6.2 to drop reference of SPA with a backend 720 component being a public client 722 o Expanded the architecture section to explicitly mention three 723 architectural patterns available to JS apps 725 -01 727 o Incorporated feedback from Torsten Lodderstedt 729 o Updated abstract 731 o Clarified the definition of browser-based apps to not exclude 732 applications cached in the browser, e.g. via Service Workers 734 o Clarified use of the state parameter for CSRF protection 736 o Added background information about the original reason the 737 implicit flow was created due to lack of CORS support 739 o Clarified the same-domain use case where the SPA and API share a 740 cookie domain 742 o Moved historic note about the fragment URL into the Overview 744 Appendix C. Acknowledgements 746 The authors would like to acknowledge the work of William Denniss and 747 John Bradley, whose recommendation for native apps informed many of 748 the best practices for browser-based applications. The authors would 749 also like to thank Hannes Tschofenig and Torsten Lodderstedt, the 750 attendees of the Internet Identity Workshop 27 session at which this 751 BCP was originally proposed, and the following individuals who 752 contributed ideas, feedback, and wording that shaped and formed the 753 final specification: 755 Annabelle Backman, Brian Campbell, Brock Allen, Christian Mainka, 756 Daniel Fett, George Fletcher, Hannes Tschofenig, John Bradley, Joseph 757 Heenan, Justin Richer, Karl McGuinness, Leo Tohill, Tomek Stojecki, 758 Torsten Lodderstedt, and Vittorio Bertocci. 760 Authors' Addresses 762 Aaron Parecki 763 Okta 765 Email: aaron@parecki.com 766 URI: https://aaronparecki.com 767 David Waite 768 Ping Identity 770 Email: david@alkaline-solutions.com