Client security measures
In this document, we present a list of important security measures that need to be taken into account when implementing clients that integrate towards the authentication and authorization APIs for CONNECT ID.
Store secrets securely
- Client ID - The client ID is considered public, and there are no requirements on how to store it.
- Client secret - Confidential clients (e.g. a web application or a native app with a server-side component) will get a client secret issued by the authorization server to be used to authenticate the client to the authorization server. The client secret must be stored in a way that it is not available for third parties. For instance, a client that is configured to be confidential that consists of a native app and a server-side component, must only store the client secret in the server-side component, and not in the native app itself. Public clients (e.g. a pure native app without a server-side component), will not be issued a client secret by the authorization sever. This makes it impossible to authenticate the client to the authorization server, and there will therefore exist restrictions on the functionality available to public clients.
- Authorization code - This is a short-lived provisional token with one-time usage restriction for fetching other tokens. The authorization code should not be stored at all, but rather exchanged for access/refresh/ID token as soon as the client gets hold of it.
- Access/refresh/ID token - The access token must be stored securely, e.g. in the device's secure storage for pure native apps (public clients). However, since it is short-lived, it may be kept only in memory. Refresh and ID tokens and potential service-specific session IDs must be stored securely, e.g. in the device's secure storage for pure native apps (public clients). For confidential clients, access, refresh, and ID tokens should only be stored server-side and out of reach for third parties. For example, none of these tokens should be stored in cookies.
Encrypt all communication to and from clients
Encryption could be done e.g. using TLS/SSL (HTTPS). CONNECT only allows use of TLS/SSL (HTTPS) for requests towards its authorization server and resource servers. Service providers need to make sure that all other communication to and from the clients, e.g. with service-specific resource servers, is encrypted appropriately.
Protect client callback endpoint against CSRF attacks
Clients must protect the redirect URI client callback endpoint against cross-site request forgery (CSRF) attacks, according to section 10.12 in the OAuth specification (RFC 6749). The recommended way to avoid CSRF attacks is to supply a cryptographically random value in the state parameter for the authorization request and verify it for the response in the client callback endpoint, ref client sample code. Please see section 10.12 in the OAuth specification (RFC 6749) and section 184.108.40.206 in the OAuth 2.0 Threat Model and Security Considerations specification (RFC 6819) for details. Note that no confidential data should be passed in the state parameter.
Validate access token for all access to protected resources
Clients must validate the access token for all access to protected resources, including its own service-specific protected resources. As mentioned in the access token validation documentation, this should be done according to section 7 in the OAuth specification (RFC 6749) and the OAuth bearer token usage specification (RFC 6750).
Validate ID token if the openid scope value is used
If the client is requesting an ID token by asking for the openid scope value, the returned ID token must be validated. As mentioned in the ID token validation documentation, this should be done according to the OpenID Connect Core spec, section 220.127.116.11.
Recommendation: Use the SDKs for Android and iOS apps
For Android and iOS apps, we recommend using the respective CONNECT SDKs. These SDKs handle authenticating the user and authorizing the app. See the native app guide for more information about features and implementation. The SDKs strive to achieve both high security and a pleasant user experience for the user. The SDKs use the latest platform features, and handle graceful degradation for older versions. The projects are open source, and any security concerns can be submitted on the project page.
Recommendation: Use an external browser for authorization request for native apps
Native apps typically have a number of different choices for what kind of browser to use for redirects to the /authorize endpoint. Typical choices are:
- An external browser (the system browser).
- A secure embedded browser that provides sandboxed integration with an external browser. Examples: Safari View Controller on iOS and Chrome Custom Tabs on Android.
- A less secure embedded browser. Example: WebView.
For native apps on platforms that we do not provide an SDK for, we recommend using an external browser (i.e. not an embedded browser). One main reason is that using an embedded browser defeats the purpose of OAuth, which is that the end user should only supply their credentials directly to the authorization server, and not to or via the client.
Despite the important security advantages of using an external browser, it is relatively common to use embedded browsers for third party login in apps. Apple does even require that a user should be able to log in without opening an external browser, in order for an app to be accepted for the App Store. Therefore, an embedded browser has to be used for iOS apps and may be used for apps on other platforms as well. If the SDK is not used for an iOS app, we recommend using Safari View Controller, available on iOS 9 and onward. If neither the SDK nor an external browser is used for an Android app, we recommend using Chrome Custom Tabs, available with Chrome 45 on Android 4.1 and onward.
We discourage using WebViews for the following reasons:
- Security - The app has complete control of the WebView layer, opening up for the possibility that the end user's credentials are captured by the app (phishing attacks). When using an external or secure embedded browser, this is much harder to do, since the browser is run in a process separate from the app which prevents it from getting access to user input.
- Trust - The amount of control the app has over the WebView layer will typically result in a range of different client-specific adaptations, e.g. removing the address bar and doing significant changes to layout and styling. When using an external or secure embedded browser, this is not possible and users will get consistent user experience, which is good for two reasons. Firstly, well-known visual protections like the SSL lock and address bar will always be there, which will contribute to end users trusting that they supply their credentials securely to the right place. Secondly, consistent user experience for all apps using CONNECT ID for login will train users what to expect and will make it easier for them to detect potential phishing attacks.
- User convenience - For WebViews, cookies are sandboxed per application, which means that cookies are not shared between applications. The consequence is that the single sign-on (SSO) functionality, which is very convenient for end users, will not work if WebViews are used. If an external browser or a secure browser that integrates with an external browser is used instead, features like password autofill will be available in addition to SSO. In addition to increased user convenience, this will probably increase end user trust, as well as conversion rates.
- Developer convenience - For the app developer, the clear separation between an external or secure embedded browser and the app makes the integration with the browser simpler and less prone to errors and unnecessary custom adaptations than when using a WebView.
Recommendation: Prefer custom scheme for redirect URI for native apps
For native apps on platforms that support deep linking, we recommend using a custom URI scheme for the redirect URI and registering it in the OS in order to get redirected back to the client through deep linking. This is the preferred approach if an external browser or a secure embedded browser like Safari View Controller or Chrome Custom Tabs is used.
Alternative ways for redirecting back to the client are typically more inconvenient. One alternative is to use a URN for the redirect URI which results in the authorization code to be delivered in the title of an HTML page which the client potentially can extract. Another alternative is to define a localhost URL for the redirect URI and start a web server in the app that is hosting a callback endpoint. Any of these alternatives may be used by native apps on platforms that do not support deep linking, see choosing a redirect URI for details. Note that native apps are not allowed to register URLs pointing to an external host for the redirect URI, ref the description of the application_type metadata field in section 2 in the OpenID Connect client registration specification.
For apps using a less secure embedded browser in the form of a WebView, despite our recommendations against it, the form of the redirect URI does not matter much since the app has a lot of control over what is happening in the WebView. We therefore suggest that a custom redirect URI is used in this case as well, and that the app simply overrides loading the URI in the WebView, in order to receive the redirect from the authorization server and dismiss the WebView.