> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-feat-acul-js-sdk-1-7-0-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Describes how to use universal links rather than custom URL schemes to verify the legitimacy of authentication data.

# Measures Against Application Impersonation

Native applications use the [Authorization Code Flow with PKCE](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) authentication flow and employ a `redirect_uri` to return control to the application after login. After the URI loads in the device’s browser, the application typically opens automatically to allow the user to continue their journey.

Historically, mobile application used [custom URI schemes](https://developers.google.com/identity/protocols/oauth2/native-app#installed_app_redirect_methods) (e.g., `com.mycompany.myapp://oauth2redirect`). However, custom URI schemes pose a risk as more than one application on the device can register the same scheme. Mobile OSs do not include built-in mechanisms to ensure the application receiving the redirect is the intended one. In this scenario, malicious apps impersonate legitimate ones and receive the authorization response (including tokens) without user awareness, especially if single sign-on (SSO) is active due to the existence of a previous legitimate session, in which additional user interaction is not required. PKCE doesn't really help in these scenarios, as the malicious application can initiate the login flow and wait to receive the callback without user interaction.

Applications running on a local machine (e.g., desktop apps, CLIs) use the loopback interface for callbacks (e.g., [http://127.0.0.1:51089/callback](http://127.0.0.1:51089/callback) or [http://localhost:61024/callback](http://localhost:61024/callback)) are similarly at risk. In this case, another application on the same machine could listen on the same port to intercept the response.

We refer to both custom URI schemes and loopback URIs as Non-Verifiable Callback URIs because the authorization server cannot verify the receiving application in either scenario.

## Recommended mitigations for mobile applications

### Claimed HTTPS URIs (Universal Links / App Links)

Modern mobile OSs support **claimed HTTPS URIs** allows you to associate a website domain you control with your mobile app. Claimed HTTPS URIs are known as:

* Universal Links on iOS
* App Links on Android

Claimed HTTPS URIs ensure only your application handles the associated callback URL and protects against unauthorized access to sensitive authentication data.

<Note>
  Auth0 **strongly recommends** using claimed HTTPS URIs as redirect URIs for all native applications.

  * For iOS: Review [Support Universal Links](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content/#Support-universal-links).
  * For Android: Review [Android App Links](https://developer.android.com/training/app-links).
</Note>

## Recommended mitigations for all application

Auth0 cannot verify the legitimacy of the application receiving the authentication transaction results if:

* Your application is unable to support claimed HTTPS URIs due to required compatibility with older mobile OS versions
* Your application is a desktop or CLI application

As defined in the [OAuth2 for Native Apps](https://datatracker.ietf.org/doc/html/rfc8252#section-8.6) specification, Auth0 provides a mechanism to show a confirmation prompt to the user. Users confirm the application receiving the authentication result is the one they intended to access. When a non-verifiable callback URI is in use, the user is prompted to verify the application on each authentication transaction.

The confirmation screen displays when:

1. The `redirect_uri` present in the request uses a non-verifiable URI (i.e. a custom URI scheme or a loopback URI).
2. The user has not been prompted with any other screen in the current login transaction (such as when a [consent screen](/docs/get-started/applications/third-party-applications/user-consent-and-third-party-applications) populates for third-party applications, or when MFA is required).

In these cases, the application presents the end user with a confirmation prompt.

<Frame>
  <img src="https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/consent-pompt-uris.png?fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=23ce9d219b0d9bc8e68e5b74ae526bcb" alt="Measures Against App Impersonation - Confirmation Prompt" width="298" height="408" data-path="docs/images/cdy7uua7fh8z/consent-pompt-uris.png" />
</Frame>

The confirmation prompt is not shown in legacy non-OIDC-conformant flows. To learn how you can apply increased protection for your tenants and applications, review [Adopt OIDC-Conformant Authentication](/docs/authenticate/login/oidc-conformant-authentication).

#### Prompt customization

The confirmation prompt uses your custom branding and configurations defined for existing consent screens used for third-party applications. To learn more, review the Prompts section of [Customize Universal Login Page Templates](/docs/customize/login-pages/universal-login/customize-templates).

<Warning>
  Auth0 **strongly recommends** you do not disable this protection for production. Malicious applications on the device could request `id_tokens` and `access_tokens` without any interaction from the user or other indications that something has happened.
</Warning>

You can configure the confirmation prompt as a global tenant settings  or at the application-level. Application-level settings take precedence over the global tenant-level setting.

**Application-level**

1. [Navigate to Auth0 Dashboard > Applications > Application Settings > Advanced > OAuth](https://manage.auth0.com/#/applications/settings).
2. Scroll to the **Non-Verifiable Callback URI End-User Confirmation** setting.
3. Enable the toggle to activate the prompt or disable the toggle to deactivate the prompt.

<Frame>
  <img src="https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/custom-uri-override.png?fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=f253a7d3615d686fdb4d197a4501ed13" alt="Auth0 Dashboard>Settings>Advanced" data-og-width="602" width="602" data-og-height="227" height="227" data-path="docs/images/cdy7uua7fh8z/custom-uri-override.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/custom-uri-override.png?w=280&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=77aea766f88fa4aa2832ef8a76dad783 280w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/custom-uri-override.png?w=560&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=fcde7fc1707dda2b0fc5d41e945707ea 560w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/custom-uri-override.png?w=840&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=768fdeeccf57cab4cd7ba705fd49688b 840w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/custom-uri-override.png?w=1100&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=902cf0f295b6c5ba2f574dee80f3de8f 1100w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/custom-uri-override.png?w=1650&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=7e8f45cf84b1df62a30f491e0982d6a4 1650w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/custom-uri-override.png?w=2500&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=b851b7fe4b1ee9803bb343ddf6dda31d 2500w" />
</Frame>

**Global**

1. Navigate to [Auth0 Dashboard > Settings > Advanced](https://manage.auth0.com/#/tenant/advanced).
2. Find the **Non-Verifiable Callback URI End-User Confirmation** setting.
3. Enable the toggle to activate the prompt.

<Frame>
  <img src="https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png?fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=1c80b250aca8b6783e8f8c9828ac6f10" alt="Auth0 Dashboard>Tenant Settings>Advanced>Skip Custom URI toggle" data-og-width="500" width="500" data-og-height="241" height="241" data-path="docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png?w=280&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=12af89e6dd2deec3aed70d16e1bdeec6 280w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png?w=560&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=c1d38fedee5ab47da9a647bb9f099360 560w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png?w=840&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=234347f19560b534cd7ab8a16dcc942c 840w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png?w=1100&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=5bcf3e74220743c3d8a06d466ceda9d3 1100w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png?w=1650&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=944d9e01ee92f1c4c6c6338390f65aa6 1650w, https://mintcdn.com/docs-staging-feat-acul-js-sdk-1-7-0-docs/OWXKY_SYsL_iLwHj/docs/images/cdy7uua7fh8z/enable-non-verifiable-callback.png?w=2500&fit=max&auto=format&n=OWXKY_SYsL_iLwHj&q=85&s=de92d7de0814670e166e8006d70f0fad 2500w" />
</Frame>
