| < draft-ietf-oauth-native-apps-10.txt | draft-ietf-oauth-native-apps-11.txt > | |||
|---|---|---|---|---|
| OAuth Working Group W. Denniss | OAuth Working Group W. Denniss | |||
| Internet-Draft Google | Internet-Draft Google | |||
| Intended status: Best Current Practice J. Bradley | Intended status: Best Current Practice J. Bradley | |||
| Expires: October 28, 2017 Ping Identity | Expires: November 20, 2017 Ping Identity | |||
| April 26, 2017 | May 19, 2017 | |||
| OAuth 2.0 for Native Apps | OAuth 2.0 for Native Apps | |||
| draft-ietf-oauth-native-apps-10 | draft-ietf-oauth-native-apps-11 | |||
| Abstract | Abstract | |||
| OAuth 2.0 authorization requests from native apps should only be made | OAuth 2.0 authorization requests from native apps should only be made | |||
| through external user-agents, primarily the user's browser. This | through external user-agents, primarily the user's browser. This | |||
| specification details the security and usability reasons why this is | specification details the security and usability reasons why this is | |||
| the case, and how native apps and authorization servers can implement | the case, and how native apps and authorization servers can implement | |||
| this best practice. | this best practice. | |||
| Status of This Memo | Status of This Memo | |||
| skipping to change at page 1, line 35 ¶ | skipping to change at page 1, line 35 ¶ | |||
| 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 http://datatracker.ietf.org/drafts/current/. | Drafts is at http://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 October 28, 2017. | This Internet-Draft will expire on November 20, 2017. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2017 IETF Trust and the persons identified as the | Copyright (c) 2017 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 | |||
| (http://trustee.ietf.org/license-info) in effect on the date of | (http://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 | |||
| skipping to change at page 2, line 15 ¶ | skipping to change at page 2, line 15 ¶ | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | |||
| 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 3 | 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 3 | |||
| 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | 4. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 4.1. Authorization Flow for Native Apps Using the Browser . . 5 | 4.1. Authorization Flow for Native Apps Using the Browser . . 5 | |||
| 5. Using Inter-app URI Communication for OAuth . . . . . . . . . 6 | 5. Using Inter-app URI Communication for OAuth . . . . . . . . . 6 | |||
| 6. Initiating the Authorization Request from a Native App . . . 7 | 6. Initiating the Authorization Request from a Native App . . . 6 | |||
| 7. Receiving the Authorization Response in a Native App . . . . 7 | 7. Receiving the Authorization Response in a Native App . . . . 7 | |||
| 7.1. Private-use URI Scheme Redirection . . . . . . . . . . . 7 | 7.1. Private-use URI Scheme Redirection . . . . . . . . . . . 8 | |||
| 7.2. Claimed HTTPS URI Redirection . . . . . . . . . . . . . . 8 | 7.2. Claimed HTTPS URI Redirection . . . . . . . . . . . . . . 9 | |||
| 7.3. Loopback Interface Redirection . . . . . . . . . . . . . 9 | 7.3. Loopback Interface Redirection . . . . . . . . . . . . . 9 | |||
| 8. Security Considerations . . . . . . . . . . . . . . . . . . . 9 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 10 | |||
| 8.1. Protecting the Authorization Code . . . . . . . . . . . . 9 | 8.1. Protecting the Authorization Code . . . . . . . . . . . . 10 | |||
| 8.2. OAuth Implicit Flow . . . . . . . . . . . . . . . . . . . 10 | 8.2. OAuth Implicit Grant Authorization Flow . . . . . . . . . 11 | |||
| 8.3. Loopback Redirect Considerations . . . . . . . . . . . . 10 | 8.3. Loopback Redirect Considerations . . . . . . . . . . . . 11 | |||
| 8.4. Registration of Native App Clients . . . . . . . . . . . 11 | 8.4. Registration of Native App Clients . . . . . . . . . . . 11 | |||
| 8.5. Client Authentication . . . . . . . . . . . . . . . . . . 12 | 8.5. Client Authentication . . . . . . . . . . . . . . . . . . 12 | |||
| 8.6. Client Impersonation . . . . . . . . . . . . . . . . . . 12 | 8.6. Client Impersonation . . . . . . . . . . . . . . . . . . 12 | |||
| 8.7. Phishability of In-App Browser Tabs . . . . . . . . . . . 12 | 8.7. Phishability of In-App Browser Tabs . . . . . . . . . . . 13 | |||
| 8.8. Cross-App Request Forgery Protections . . . . . . . . . . 13 | 8.8. Cross-App Request Forgery Protections . . . . . . . . . . 13 | |||
| 8.9. Authorization Server Mix-Up Mitigation . . . . . . . . . 13 | 8.9. Authorization Server Mix-Up Mitigation . . . . . . . . . 14 | |||
| 8.10. Non-Browser External User-Agents . . . . . . . . . . . . 13 | 8.10. Non-Browser External User-Agents . . . . . . . . . . . . 14 | |||
| 8.11. Embedded User-Agents . . . . . . . . . . . . . . . . . . 14 | 8.11. Embedded User-Agents . . . . . . . . . . . . . . . . . . 14 | |||
| 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 | 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 | |||
| 10.2. Informative References . . . . . . . . . . . . . . . . . 15 | 10.2. Informative References . . . . . . . . . . . . . . . . . 16 | |||
| Appendix A. Server Support Checklist . . . . . . . . . . . . . . 16 | Appendix A. Server Support Checklist . . . . . . . . . . . . . . 16 | |||
| Appendix B. Operating System Specific Implementation Details . . 16 | Appendix B. Operating System Specific Implementation Details . . 17 | |||
| B.1. iOS Implementation Details . . . . . . . . . . . . . . . 17 | B.1. iOS Implementation Details . . . . . . . . . . . . . . . 17 | |||
| B.2. Android Implementation Details . . . . . . . . . . . . . 17 | B.2. Android Implementation Details . . . . . . . . . . . . . 18 | |||
| B.3. Windows Implementation Details . . . . . . . . . . . . . 18 | B.3. Windows Implementation Details . . . . . . . . . . . . . 18 | |||
| B.4. macOS Implementation Details . . . . . . . . . . . . . . 18 | B.4. macOS Implementation Details . . . . . . . . . . . . . . 19 | |||
| B.5. Linux Implementation Details . . . . . . . . . . . . . . 19 | B.5. Linux Implementation Details . . . . . . . . . . . . . . 19 | |||
| Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 19 | Appendix C. Acknowledgements . . . . . . . . . . . . . . . . . . 19 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 19 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 | |||
| 1. Introduction | 1. Introduction | |||
| The OAuth 2.0 [RFC6749] authorization framework documents two | The OAuth 2.0 [RFC6749] authorization framework documents two | |||
| approaches in Section 9 for native apps to interact with the | approaches in Section 9 for native apps to interact with the | |||
| authorization endpoint: an embedded user-agent, and an external user- | authorization endpoint: an embedded user-agent, and an external user- | |||
| agent. | agent. | |||
| This best current practice requires that only external user-agents | This best current practice requires that only external user-agents | |||
| like the browser are used for OAuth by native apps. It documents how | like the browser are used for OAuth by native apps. It documents how | |||
| skipping to change at page 3, line 28 ¶ | skipping to change at page 3, line 28 ¶ | |||
| "OPTIONAL" in this document are to be interpreted as described in Key | "OPTIONAL" in this document are to be interpreted as described in Key | |||
| words for use in RFCs to Indicate Requirement Levels [RFC2119]. If | words for use in RFCs to Indicate Requirement Levels [RFC2119]. If | |||
| these words are used without being spelled in uppercase then they are | these words are used without being spelled in uppercase then they are | |||
| to be interpreted with their normal natural language meanings. | to be interpreted with their normal natural language meanings. | |||
| 3. Terminology | 3. Terminology | |||
| In addition to the terms defined in referenced specifications, this | In addition to the terms defined in referenced specifications, this | |||
| document uses the following terms: | document uses the following terms: | |||
| "native app" An application that is installed by the user to their | "native app" An app or application that is installed by the user to | |||
| device, as distinct from a web app that runs in the browser | their device, as distinct from a web app that runs in the browser | |||
| context only. Apps implemented using web-based technology but | context only. Apps implemented using web-based technology but | |||
| distributed as a native app, so-called hybrid apps, are considered | distributed as a native app, so-called hybrid apps, are considered | |||
| equivalent to native apps for the purpose of this specification. | equivalent to native apps for the purpose of this specification. | |||
| "app" In this document, "app" means a "native app" unless further | ||||
| specified. | ||||
| "app store" An ecommerce store where users can download and purchase | ||||
| apps. | ||||
| "OAuth" In this document, OAuth refers to OAuth 2.0 [RFC6749]. | "OAuth" In this document, OAuth refers to OAuth 2.0 [RFC6749]. | |||
| "external user-agent" A user-agent capable of handling the | "external user-agent" A user-agent capable of handling the | |||
| authorization request that is a separate entity or security domain | authorization request that is a separate entity or security domain | |||
| to the native app making the request (such as a browser), such | to the native app making the request (such as a browser), such | |||
| that the app cannot access the cookie storage, nor inspect or | that the app cannot access the cookie storage, nor inspect or | |||
| modify page content. | modify page content. | |||
| "embedded user-agent" A user-agent hosted inside the native app | "embedded user-agent" A user-agent hosted inside the native app | |||
| itself (such as via a web-view), with which the app has control | itself (such as via a web-view), with which the app has control | |||
| over to the extent it is capable of accessing the cookie storage | over to the extent it is capable of accessing the cookie storage | |||
| and/or modify the page content. | and/or modifying the page content. | |||
| "app" Shorthand for "native app". | ||||
| "app store" An ecommerce store where users can download and purchase | ||||
| apps. | ||||
| "browser" The operating system's default browser, pre-installed as | ||||
| part of the operating system, or installed and set as default by | ||||
| the user. | ||||
| "browser tab" An open page of the browser. Browser typically have | "browser" The default application launched by the operating system | |||
| multiple "tabs" representing various open pages. | to handle "http" and "https" scheme URI content. | |||
| "in-app browser tab" A full page browser with limited navigation | "in-app browser tab" A programmatic instantiation of the browser | |||
| capabilities that is displayed inside a host app, but retains the | that is displayed inside a host app, but retains the full security | |||
| full security properties and authentication state of the browser. | properties and authentication state of the browser. Has different | |||
| Has different platform-specific product names, such as | platform-specific product names, such as SFSafariViewController on | |||
| SFSafariViewController on iOS, and Custom Tabs on Android. | iOS, and Custom Tabs on Android. | |||
| "inter-app communication" Communication between two apps on a | "inter-app communication" Communication between two apps on a | |||
| device. | device. | |||
| "claimed HTTPS URI" Some platforms allow apps to claim a HTTPS | "claimed HTTPS URI" Some platforms allow apps to claim a HTTPS | |||
| scheme URI after proving ownership of the domain name. URIs | scheme URI after proving ownership of the domain name. URIs | |||
| claimed in such a way are then opened in the app instead of the | claimed in such a way are then opened in the app instead of the | |||
| browser. | browser. | |||
| "private-use URI scheme" A private-use URI scheme defined by the app | "private-use URI scheme" A private-use URI scheme defined by the app | |||
| skipping to change at page 5, line 15 ¶ | skipping to change at page 5, line 10 ¶ | |||
| Native app authorization requests that use the browser are more | Native app authorization requests that use the browser are more | |||
| secure and can take advantage of the user's authentication state. | secure and can take advantage of the user's authentication state. | |||
| Being able to use the existing authentication session in the browser | Being able to use the existing authentication session in the browser | |||
| enables single sign-on, as users don't need to authenticate to the | enables single sign-on, as users don't need to authenticate to the | |||
| authorization server each time they use a new app (unless required by | authorization server each time they use a new app (unless required by | |||
| authorization server policy). | authorization server policy). | |||
| Supporting authorization flows between a native app and the browser | Supporting authorization flows between a native app and the browser | |||
| is possible without changing the OAuth protocol itself, as the | is possible without changing the OAuth protocol itself, as the | |||
| authorization request and response are already defined in terms of | authorization request and response are already defined in terms of | |||
| URIs, which emcompasses URIs that can be used for inter-process | URIs, which encompasses URIs that can be used for inter-app | |||
| communication. Some OAuth server implementations that assume all | communication. Some OAuth server implementations that assume all | |||
| clients are confidential web-clients will need to add an | clients are confidential web-clients will need to add an | |||
| understanding of public native app clients and the types of redirect | understanding of public native app clients and the types of redirect | |||
| URIs they use to support this best practice. | URIs they use to support this best practice. | |||
| 4.1. Authorization Flow for Native Apps Using the Browser | 4.1. Authorization Flow for Native Apps Using the Browser | |||
| +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | |||
| | User Device | | | User Device | | |||
| | | | | | | |||
| skipping to change at page 5, line 50 ¶ | skipping to change at page 5, line 45 ¶ | |||
| | +---------------------------+ | +---------------+ | | +---------------------------+ | +---------------+ | |||
| | | | | (2) Authz Request | | | | | | | (2) Authz Request | | | |||
| | | Browser |--------------------->| Authorization | | | | Browser |--------------------->| Authorization | | |||
| | | |<---------------------| Endpoint | | | | |<---------------------| Endpoint | | |||
| | +---------------------------+ | (3) Authz Code | | | | +---------------------------+ | (3) Authz Code | | | |||
| | | +---------------+ | | | +---------------+ | |||
| +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | |||
| Figure 1: Native App Authorization via External User-agent | Figure 1: Native App Authorization via External User-agent | |||
| Figure 1 illustrates the interaction of the native app with the | Figure 1 illustrates the interaction of the native app with a browser | |||
| system browser to authorize the user via an external user-agent. | external user-agent to authorize the user. | |||
| (1) The client app opens a browser tab with the authorization | (1) The client app opens a browser tab with the authorization | |||
| request. | request. | |||
| (2) Authorization endpoint receives the authorization request, | (2) Authorization endpoint receives the authorization request, | |||
| authenticates the user and obtains authorization. | authenticates the user and obtains authorization. | |||
| Authenticating the user may involve chaining to other | Authenticating the user may involve chaining to other | |||
| authentication systems. | authentication systems. | |||
| (3) Authorization server issues an authorization code to the | (3) Authorization server issues an authorization code to the | |||
| skipping to change at page 6, line 32 ¶ | skipping to change at page 6, line 29 ¶ | |||
| tokens requested. | tokens requested. | |||
| 5. Using Inter-app URI Communication for OAuth | 5. Using Inter-app URI Communication for OAuth | |||
| Just as URIs are used for OAuth 2.0 [RFC6749] on the web to initiate | Just as URIs are used for OAuth 2.0 [RFC6749] on the web to initiate | |||
| the authorization request and return the authorization response to | the authorization request and return the authorization response to | |||
| the requesting website, URIs can be used by native apps to initiate | the requesting website, URIs can be used by native apps to initiate | |||
| the authorization request in the device's browser and return the | the authorization request in the device's browser and return the | |||
| response to the requesting native app. | response to the requesting native app. | |||
| By applying the same principles from the web to native apps, we gain | By adopting the same methods used on the web for OAuth, benefits seen | |||
| benefits seen on the web, like the usability of a single sign-on | in the web context like the usability of a single sign-on session and | |||
| session and the security of a separate authentication context. It | the security of a separate authentication context are likewise gained | |||
| also reduces the implementation complexity by reusing similar flows | in the native app context. Re-using the same approach also reduces | |||
| as the web, and increases interoperability by relying on standards- | the implementation complexity and increases interoperability by | |||
| based web flows that are not specific to a particular platform. | relying on standards-based web flows that are not specific to a | |||
| particular platform. | ||||
| Native apps MUST use an external user-agent to perform OAuth | ||||
| authentication requests. This is achieved by opening the | ||||
| authorization request in the browser (detailed in Section 6), and | ||||
| using a redirect URI that will return the authorization response back | ||||
| to the native app, as defined in Section 7. | ||||
| This best practice focuses on the browser as the RECOMMENDED external | To conform to this best practice, native apps MUST use an external | |||
| user-agent for native apps. Other external user-agents, such as a | user-agent to perform OAuth authentication requests. This is | |||
| native app provided by the authorization server may meet the criteria | achieved by opening the authorization request in the browser | |||
| set out in this best practice, including using the same redirection | (detailed in Section 6), and using a redirect URI that will return | |||
| URI properties, but their use is out of scope for this specification. | the authorization response back to the native app, as defined in | |||
| Section 7. | ||||
| 6. Initiating the Authorization Request from a Native App | 6. Initiating the Authorization Request from a Native App | |||
| The authorization request is created as per OAuth 2.0 [RFC6749], and | Native apps needing user authorization create an authorization | |||
| opened in the user's browser using platform-specific APIs for that | request URI with the authorization code grant type per Section 4.1 of | |||
| purpose. | OAuth 2.0 [RFC6749], using a redirect URI capable of being received | |||
| by the native app. | ||||
| The function of the redirect URI for a native app authorization | The function of the redirect URI for a native app authorization | |||
| request is similar to that of a web-based authorization request. | request is similar to that of a web-based authorization request. | |||
| Rather than returning the authorization response to the OAuth | Rather than returning the authorization response to the OAuth | |||
| client's server, the redirect URI used by a native app returns the | client's server, the redirect URI used by a native app returns the | |||
| response to the app. The various options for a redirect URI that | response to the app. Several options for a redirect URI that will | |||
| will return the code to the native app are documented in Section 7. | return the authorization response to the native app in different | |||
| Any redirect URI that allows the app to receive the URI and inspect | platforms are documented in Section 7. Any redirect URI that allows | |||
| its parameters is viable. | the app to receive the URI and inspect its parameters is viable. | |||
| Public native app clients MUST implement the Proof Key for Code | ||||
| Exchange (PKCE [RFC7636]) extension to OAuth, and authorization | ||||
| servers MUST support PKCE for such clients, for the reasons detailed | ||||
| in Section 8.1. | ||||
| After constructing the authorization request URI, the app uses | ||||
| platform-specific APIs to open the URI in an external user-agent. | ||||
| Typically the external user-agent used is the default browser, that | ||||
| is, the application configured for handling "http" and "https" scheme | ||||
| URIs on the system, but different browser selection criteria and | ||||
| other categories of external user-agents MAY be used. | ||||
| This best practice focuses on the browser as the RECOMMENDED external | ||||
| user-agent for native apps. An external user-agent designed | ||||
| specifically for processing authorization requests capable of | ||||
| processing the request and redirect URIs in the same way MAY also be | ||||
| used. Other external user-agents, such as a native app provided by | ||||
| the authorization server may meet the criteria set out in this best | ||||
| practice, including using the same redirection URI properties, but | ||||
| their use is out of scope for this specification. | ||||
| Some platforms support a browser feature known as in-app browser | Some platforms support a browser feature known as in-app browser | |||
| tabs, where an app can present a tab of the browser within the app | tabs, where an app can present a tab of the browser within the app | |||
| context without switching apps, but still retain key benefits of the | context without switching apps, but still retain key benefits of the | |||
| browser such as a shared authentication state and security context. | browser such as a shared authentication state and security context. | |||
| On platforms where they are supported, it is RECOMMENDED for | On platforms where they are supported, it is RECOMMENDED for | |||
| usability reasons that apps use in-app browser tabs for the | usability reasons that apps use in-app browser tabs for the | |||
| Authorization Request. | authorization request. | |||
| 7. Receiving the Authorization Response in a Native App | 7. Receiving the Authorization Response in a Native App | |||
| There are several redirect URI options available to native apps for | There are several redirect URI options available to native apps for | |||
| receiving the authorization response from the browser, the | receiving the authorization response from the browser, the | |||
| availability and user experience of which varies by platform. | availability and user experience of which varies by platform. | |||
| To fully support this best practice, authorization servers MUST | To fully support this best practice, authorization servers MUST | |||
| support the following three redirect URI options. Native apps MAY | support the following three redirect URI options. Native apps MAY | |||
| use whichever redirect option suits their needs best, taking into | use whichever redirect option suits their needs best, taking into | |||
| skipping to change at page 8, line 32 ¶ | skipping to change at page 8, line 46 ¶ | |||
| redirect to help avoid this problem. | redirect to help avoid this problem. | |||
| Following the requirements of [RFC3986] Section 3.2, as there is no | Following the requirements of [RFC3986] Section 3.2, as there is no | |||
| naming authority for private-use URI scheme redirects, only a single | naming authority for private-use URI scheme redirects, only a single | |||
| slash ("/") appears after the scheme component. A complete example | slash ("/") appears after the scheme component. A complete example | |||
| of a redirect URI utilizing a private-use URI scheme: | of a redirect URI utilizing a private-use URI scheme: | |||
| com.example.app:/oauth2redirect/example-provider | com.example.app:/oauth2redirect/example-provider | |||
| When the authentication server completes the request, it redirects to | When the authentication server completes the request, it redirects to | |||
| the client's redirection URI like it would any redirect URI. As the | the client's redirection URI as it would normally. As the | |||
| redirection URI uses a custom scheme it results in the operating | redirection URI uses a custom scheme it results in the operating | |||
| system launching the native app, passing in the URI as a launch | system launching the native app, passing in the URI as a launch | |||
| parameter. The native app then processes the authorization response | parameter. The native app then processes the authorization response | |||
| like normal. | like normal. | |||
| 7.2. Claimed HTTPS URI Redirection | 7.2. Claimed HTTPS URI Redirection | |||
| Some operating systems allow apps to claim HTTPS scheme URIs in | Some operating systems allow apps to claim HTTPS scheme URIs in | |||
| domains they control. When the browser encounters a claimed URI, | domains they control. When the browser encounters a claimed URI, | |||
| instead of the page being loaded in the browser, the native app is | instead of the page being loaded in the browser, the native app is | |||
| launched with the URI supplied as a launch parameter. | launched with the URI supplied as a launch parameter. | |||
| Such URIs can be used as OAuth redirect URIs. They are | Such URIs can be used as OAuth redirect URIs. They are | |||
| indistinguishable from OAuth redirects of web-based clients. An | indistinguishable from OAuth redirects of web-based clients. An | |||
| example is: | example is: | |||
| https://app.example.com/oauth2redirect/example-provider | https://app.example.com/oauth2redirect/example-provider | |||
| App-claimed HTTPS redirect URIs have some advantages in that the | App-claimed HTTPS redirect URIs have some advantages in that the | |||
| identity of the destination app is guaranteed by the operating | identity of the destination app is guaranteed by the operating | |||
| system. Due to this reason, they SHOULD be used over the other | system. For this reason, they SHOULD be used in preference to the | |||
| redirect choices for native apps where possible. | other redirect options for native apps where possible. | |||
| Claimed HTTPS redirect URIs function as normal HTTPS redirects from | Claimed HTTPS redirect URIs function as normal HTTPS redirects from | |||
| the perspective of the authorization server, though as stated in | the perspective of the authorization server, though as stated in | |||
| Section 8.4, it REQUIRED that the authorization server is able to | Section 8.4, it is REQUIRED that the authorization server is able to | |||
| distinguish between public native app clients that use app-claimed | distinguish between public native app clients that use app-claimed | |||
| HTTPS redirect URIs and confidential web clients. | HTTPS redirect URIs and confidential web clients. | |||
| 7.3. Loopback Interface Redirection | 7.3. Loopback Interface Redirection | |||
| Native apps that are able to open a port on the loopback network | Native apps that are able to open a port on the loopback network | |||
| interface without needing special permissions (typically, those on | interface without needing special permissions (typically, those on | |||
| desktop operating systems) can use the loopback network interface to | desktop operating systems) can use the loopback interface to receive | |||
| receive the OAuth redirect. | the OAuth redirect. | |||
| Loopback redirect URIs use the HTTP scheme and are constructed with | Loopback redirect URIs use the HTTP scheme and are constructed with | |||
| the loopback IP literal and whatever port the client is listening on. | the loopback IP literal and whatever port the client is listening on. | |||
| That is, "http://127.0.0.1:{port}/{path}" for IPv4, and | That is, "http://127.0.0.1:{port}/{path}" for IPv4, and | |||
| "http://[::1]:{port}/{path}" for IPv6. A complete example of such a | "http://[::1]:{port}/{path}" for IPv6. An example redirect using the | |||
| redirect with a randomly assigned port: | IPv4 loopback interface with a randomly assigned port: | |||
| http://127.0.0.1:61023/oauth2redirect/example-provider | http://127.0.0.1:50719/oauth2redirect/example-provider | |||
| An example redirect using the IPv6 loopback interface with a randomly | ||||
| assigned port: | ||||
| http://[::1]:61023/oauth2redirect/example-provider | ||||
| The authorization server MUST allow any port to be specified at the | The authorization server MUST allow any port to be specified at the | |||
| time of the request for loopback IP redirect URIs, to accommodate | time of the request for loopback IP redirect URIs, to accommodate | |||
| clients that obtain an available ephemeral port from the operating | clients that obtain an available ephemeral port from the operating | |||
| system at the time of the request. | system at the time of the request. | |||
| Clients SHOULD NOT assume the device supports a particular version of | ||||
| the Internet Protocol. It is RECOMMENDED that clients attempt to | ||||
| bind to the loopback interface using both IPv4 and IPv6, and use | ||||
| whichever is available. | ||||
| 8. Security Considerations | 8. Security Considerations | |||
| 8.1. Protecting the Authorization Code | 8.1. Protecting the Authorization Code | |||
| The redirect URI options documented in Section 7 share the benefit | The redirect URI options documented in Section 7 share the benefit | |||
| that only a native app on the same device can receive the | that only a native app on the same device can receive the | |||
| authorization code which limits the attack surface, however code | authorization code which limits the attack surface, however code | |||
| interception by a native app other than the intended app may still be | interception by a native app other than the intended app may still be | |||
| possible. | possible. | |||
| A limitation of using private-use URI schemes for redirect URIs is | A limitation of using private-use URI schemes for redirect URIs is | |||
| that multiple apps can typically register the same scheme, which | that multiple apps can typically register the same scheme, which | |||
| makes it indeterminate as to which app will receive the Authorization | makes it indeterminate as to which app will receive the Authorization | |||
| Code. PKCE [RFC7636] details how this limitation can be used to | Code. PKCE [RFC7636] details how this limitation can be used to | |||
| execute a code interception attack (see Figure 1). | execute a code interception attack (see Figure 1). | |||
| Loopback IP based redirect URIs may be susceptible to interception by | Loopback IP based redirect URIs may be susceptible to interception by | |||
| other apps listening on the same loopback interface. | other apps listening on the same loopback interface. | |||
| As most forms of inter-app URI-based communication sends data over | As most forms of inter-app URI-based communication send data over | |||
| insecure local channels, eavesdropping and interception of the | insecure local channels, eavesdropping and interception of the | |||
| authorization response is a risk for native apps. App-claimed HTTPS | authorization response is a risk for native apps. App-claimed HTTPS | |||
| redirects are hardened against this type of attack due to the | redirects are hardened against this type of attack due to the | |||
| presence of the URI authority, but they are still public clients and | presence of the URI authority, but they are still public clients and | |||
| the URI is still transmitted over local channels with unknown | the URI is still transmitted over local channels with unknown | |||
| security properties. | security properties. | |||
| The Proof Key for Code Exchange by OAuth Public Clients (PKCE | The Proof Key for Code Exchange by OAuth Public Clients (PKCE | |||
| [RFC7636]) standard was created specifically to mitigate against this | [RFC7636]) standard was created specifically to mitigate against this | |||
| attack. It is a Proof of Possession extension to OAuth 2.0 that | attack. It is a Proof of Possession extension to OAuth 2.0 that | |||
| protects the code grant from being used if it is intercepted. It | protects the code grant from being used if it is intercepted. It | |||
| achieves this by having the client generate a secret verifier, a hash | achieves this by having the client generate a secret verifier, a hash | |||
| of which it passes in the initial authorization request, and which it | of which it passes in the initial authorization request, and which it | |||
| must present in full when redeeming the authorization code grant. An | must present in full when redeeming the authorization code grant. An | |||
| app that intercepted the authorization code would not be in | app that intercepted the authorization code would not be in | |||
| possession of this secret, rendering the code useless. | possession of this secret, rendering the code useless. | |||
| Public native app clients MUST protect the authorization request with | Section 8.1 requires that both clients and servers use PKCE for | |||
| PKCE [RFC7636]. Authorization servers MUST support PKCE [RFC7636] | public native app clients. Authorization servers SHOULD reject | |||
| for public native app clients. Authorization servers SHOULD reject | ||||
| authorization requests from native apps that don't use PKCE by | authorization requests from native apps that don't use PKCE by | |||
| returning an error message as defined in Section 4.4.1 of PKCE | returning an error message as defined in Section 4.4.1 of PKCE | |||
| [RFC7636]. | [RFC7636]. | |||
| 8.2. OAuth Implicit Flow | 8.2. OAuth Implicit Grant Authorization Flow | |||
| The OAuth 2.0 Implicit Flow as defined in Section 4.2 of OAuth 2.0 | The OAuth 2.0 implicit grant authorization flow as defined in | |||
| [RFC6749] generally works with the practice of performing the | Section 4.2 of OAuth 2.0 [RFC6749] generally works with the practice | |||
| authorization request in the browser, and receiving the authorization | of performing the authorization request in the browser, and receiving | |||
| response via URI-based inter-app communication. However, as the | the authorization response via URI-based inter-app communication. | |||
| Implicit Flow cannot be protected by PKCE (which is a required in | However, as the Implicit Flow cannot be protected by PKCE (which is a | |||
| Section 8.1), the use of the Implicit Flow with native apps is NOT | required in Section 8.1), the use of the Implicit Flow with native | |||
| RECOMMENDED. | apps is NOT RECOMMENDED. | |||
| Tokens granted via the implicit flow also cannot be refreshed without | Tokens granted via the implicit flow also cannot be refreshed without | |||
| user interaction, making the code flow - which can issue refresh | user interaction, making the authorization code grant flow - which | |||
| tokens - the more practical option for native app authorizations that | can issue refresh tokens - the more practical option for native app | |||
| require refreshing. | authorizations that require refreshing. | |||
| 8.3. Loopback Redirect Considerations | 8.3. Loopback Redirect Considerations | |||
| Loopback interface redirect URIs use the "http" scheme (i.e. without | Loopback interface redirect URIs use the "http" scheme (i.e., without | |||
| TLS). This is acceptable for loopback interface redirect URIs as the | TLS). This is acceptable for loopback interface redirect URIs as the | |||
| HTTP request never leaves the device. | HTTP request never leaves the device. | |||
| Clients should open the network port only when starting the | Clients should open the network port only when starting the | |||
| authorization request, and close it once the response is returned. | authorization request, and close it once the response is returned. | |||
| Clients should listen on the loopback network interface only, to | Clients should listen on the loopback network interface only, to | |||
| avoid interference by other network actors. | avoid interference by other network actors. | |||
| While redirect URIs using localhost (i.e. | While redirect URIs using localhost (i.e., | |||
| "http://localhost:{port}/") function similarly to loopback IP | "http://localhost:{port}/") function similarly to loopback IP | |||
| redirects described in Section 7.3, the use of "localhost" is NOT | redirects described in Section 7.3, the use of "localhost" is NOT | |||
| RECOMMENDED. Specifying a redirect URI with the loopback IP literal | RECOMMENDED. Specifying a redirect URI with the loopback IP literal | |||
| rather than localhost avoids inadvertently listening on network | rather than localhost avoids inadvertently listening on network | |||
| interfaces other than the loopback interface. It is also less | interfaces other than the loopback interface. It is also less | |||
| susceptible to client side firewalls, and misconfigured host name | susceptible to client side firewalls, and misconfigured host name | |||
| resolution on the user's device. | resolution on the user's device. | |||
| 8.4. Registration of Native App Clients | 8.4. Registration of Native App Clients | |||
| skipping to change at page 13, line 8 ¶ | skipping to change at page 13, line 32 ¶ | |||
| Importantly, such an attack that uses a web-view to fake an in-app | Importantly, such an attack that uses a web-view to fake an in-app | |||
| browser tab will always start with no authentication state. If all | browser tab will always start with no authentication state. If all | |||
| native apps use the techniques described in this best practice, users | native apps use the techniques described in this best practice, users | |||
| will not need to sign-in frequently and thus should be suspicious of | will not need to sign-in frequently and thus should be suspicious of | |||
| any sign-in request when they should have already been signed-in. | any sign-in request when they should have already been signed-in. | |||
| This is the case even for authorization servers that require | This is the case even for authorization servers that require | |||
| occasional or frequent re-authentication, as such servers can | occasional or frequent re-authentication, as such servers can | |||
| preserve some user identifiable information from the old session, | preserve some user identifiable information from the old session, | |||
| like the email address or profile picture and display that | such as the email address or profile picture and display that | |||
| information during re-authentication. | information during re-authentication. | |||
| Users who are particularly concerned about their security may also | Users who are particularly concerned about their security may also | |||
| take the additional step of opening the request in the browser from | take the additional step of opening the request in the browser from | |||
| the in-app browser tab, and completing the authorization there, as | the in-app browser tab, and completing the authorization there, as | |||
| most implementations of the in-app browser tab pattern offer such | most implementations of the in-app browser tab pattern offer such | |||
| functionality. | functionality. | |||
| 8.8. Cross-App Request Forgery Protections | 8.8. Cross-App Request Forgery Protections | |||
| Section 5.3.5 of [RFC6819] recommends using the "state" parameter to | Section 5.3.5 of [RFC6819] recommends using the "state" parameter to | |||
| link client requests and responses to prevent CSRF attacks. | link client requests and responses to prevent CSRF (Cross Site | |||
| Request Forgery) attacks. | ||||
| It is similarly RECOMMENDED for native apps to include a high entropy | To mitigate CSRF style attacks using inter-app URI communication, it | |||
| is similarly RECOMMENDED for native apps to include a high entropy | ||||
| secure random number in the "state" parameter of the authorization | secure random number in the "state" parameter of the authorization | |||
| request, and reject any incoming authorization responses without a | request, and reject any incoming authorization responses without a | |||
| state value that matches a pending outgoing authorization request. | state value that matches a pending outgoing authorization request. | |||
| 8.9. Authorization Server Mix-Up Mitigation | 8.9. Authorization Server Mix-Up Mitigation | |||
| To protect against a compromised or malicious authorization server | To protect against a compromised or malicious authorization server | |||
| attacking another authorization server used by the same app, it is | attacking another authorization server used by the same app, it is | |||
| REQUIRED that a unique redirect URI is used for each authorization | REQUIRED that a unique redirect URI is used for each authorization | |||
| server used by the app (for example, by varying the path component), | server used by the app (for example, by varying the path component), | |||
| and that authorization responses are rejected if the redirect URI | and that authorization responses are rejected if the redirect URI | |||
| they were received on doesn't match the redirect URI in a outgoing | they were received on doesn't match the redirect URI in a outgoing | |||
| authorization request. | authorization request. | |||
| The native app MUST store the redirect URI used in the authorization | The native app MUST store the redirect URI used in the authorization | |||
| request with the authorization session data (i.e. along with "state" | request with the authorization session data (i.e., along with "state" | |||
| and other related data), and MUST verify that the URI on which the | and other related data), and MUST verify that the URI on which the | |||
| authorization response was received exactly matches it. | authorization response was received exactly matches it. | |||
| The requirements of Section 8.4 that authorization servers reject | The requirements of Section 8.4 that authorization servers reject | |||
| requests with URIs that don't match what was registered are also | requests with URIs that don't match what was registered are also | |||
| required to prevent such attacks. | required to prevent such attacks. | |||
| 8.10. Non-Browser External User-Agents | 8.10. Non-Browser External User-Agents | |||
| This best practice recommends a particular type of external user- | This best practice recommends a particular type of external user- | |||
| skipping to change at page 19, line 22 ¶ | skipping to change at page 19, line 44 ¶ | |||
| Opening the Authorization Request in the user's default browser | Opening the Authorization Request in the user's default browser | |||
| requires a distro-specific command, "xdg-open" is one such tool. | requires a distro-specific command, "xdg-open" is one such tool. | |||
| The loopback redirect is the recommended redirect choice for desktop | The loopback redirect is the recommended redirect choice for desktop | |||
| apps on Linux to receive the authorization response. | apps on Linux to receive the authorization response. | |||
| Appendix C. Acknowledgements | Appendix C. Acknowledgements | |||
| The author would like to acknowledge the work of Marius Scurtescu, | The author would like to acknowledge the work of Marius Scurtescu, | |||
| and Ben Wiley Sittler whose design for using private-use URI schemes | and Ben Wiley Sittler whose design for using private-use URI schemes | |||
| in native OAuth 2.0 clients formed the basis of Section 7.1. | in native OAuth 2.0 clients at Google formed the basis of | |||
| Section 7.1. | ||||
| The following individuals contributed ideas, feedback, and wording | The following individuals contributed ideas, feedback, and wording | |||
| that shaped and formed the final specification: | that shaped and formed the final specification: | |||
| Andy Zmolek, Steven E Wright, Brian Campbell, Paul Madsen, Nat | Andy Zmolek, Steven E Wright, Brian Campbell, Nat Sakimura, Eric | |||
| Sakimura, Iain McGinniss, Rahul Ravikumar, Eric Sachs, Breno de | Sachs, Paul Madsen, Iain McGinniss, Rahul Ravikumar, Breno de | |||
| Medeiros, Adam Dawes, Naveen Agarwal, Hannes Tschofenig, Ashish Jain, | Medeiros, Hannes Tschofenig, Ashish Jain, Erik Wahlstrom, Bill | |||
| Erik Wahlstrom, Bill Fisher, Sudhi Umarji, Michael B. Jones, Vittorio | Fisher, Sudhi Umarji, Michael B. Jones, Vittorio Bertocci, Dick | |||
| Bertocci, Dick Hardt, David Waite, and Ignacio Fiorentino. | Hardt, David Waite, Ignacio Fiorentino, Kathleen Moriarty, and Elwyn | |||
| Davies. | ||||
| Authors' Addresses | Authors' Addresses | |||
| William Denniss | William Denniss | |||
| 1600 Amphitheatre Pkwy | 1600 Amphitheatre Pkwy | |||
| Mountain View, CA 94043 | Mountain View, CA 94043 | |||
| USA | USA | |||
| Email: wdenniss@google.com | Email: wdenniss@google.com | |||
| End of changes. 47 change blocks. | ||||
| 103 lines changed or deleted | 132 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/ | ||||