# Choose secure OAuth redirect URIs for native apps

> Prefer claimed HTTPS redirects where platforms support them, use loopback for desktop apps, and reserve custom schemes for constrained cases.

Canonical URL: https://www.devobs.io/articles/native-app-oauth-redirect-uris/
By: Arjun Shah
Published: 2024-11-07T15:41:51.385Z
Updated: 2026-09-06T08:31:04.426Z
Section: Architecture

For a native OAuth client, prefer an app-claimed HTTPS redirect when the operating system can verify the association. Use a loopback redirect for desktop software that can listen on a local port. Use a private custom scheme only when platform constraints demand it, and combine every option with authorization code flow, PKCE, exact redirect matching, and transaction binding.

## Start from the interception threat

Native apps cannot safely keep a static client secret: installed copies are available to their users. The key redirect risk is interception. A malicious app may register the same custom scheme and receive the authorization response intended for the legitimate app.

The [OAuth native apps best current practice](https://www.rfc-editor.org/rfc/rfc8252) defines three redirect patterns: private-use URI schemes, claimed HTTPS schemes, and loopback interface redirects. It also requires external user agents and recommends PKCE to bind the authorization code to the client instance that started the flow.

PKCE does not make a weak redirect irrelevant, but it prevents an interceptor that lacks the verifier from redeeming the stolen code. Keep the verifier in the initiating app instance and bind state, issuer, redirect choice, and code verifier to one short-lived transaction.

## Prefer claimed HTTPS on mobile

A claimed HTTPS URI looks like a normal web URL, but the mobile operating system opens it in the app only after verifying a domain-to-app association. This gives the authorization server a globally unique HTTPS redirect and makes competing app registration harder than with a custom scheme.

Use a dedicated path such as https://login.example.test/oauth/callback and configure the platform association files correctly. Test the negative case: remove or corrupt the association and verify that codes do not land on a generic web page that exposes them. Treat domain ownership, TLS, association-file hosting, and app-signing identity as part of the OAuth security boundary.

Some platform or deployment combinations cannot support verified links reliably. Record that constraint before falling back.

## Use loopback for desktop clients

A desktop app can open a listener on the local loopback interface, launch the browser with a redirect such as http://127.0.0.1:{random-port}/callback, and accept one response. RFC 8252 permits loopback IP redirects and says authorization servers must allow the client to choose the port at request time.

Bind to loopback only, choose an ephemeral port, accept a single valid callback, validate state, and close promptly. Prefer literal loopback IP addresses to hostnames where name resolution could behave unexpectedly. Do not expose the listener on the LAN, and show a safe retry path if local firewall or endpoint software blocks it.

## Constrain custom schemes

When using a private scheme, choose a reverse-domain name under your control rather than a generic value such as myapp. Register the precise redirect. Assume another app could claim the same scheme, so PKCE is mandatory and the callback must reject a state value it did not create.

The current [OAuth 2.0 security best practice](https://www.rfc-editor.org/rfc/rfc9700) requires exact string matching of registered [redirect URIs](https://www.devobs.io/articles/oauth-redirect-uri-validation/), except for loopback port numbers, and requires public clients to use PKCE. It also warns against open redirectors. Never register wildcard callback paths to simplify multiple environments.

Separate development and production client registrations. A production authorization server should not redirect to a developer machine or an unverified test scheme.

## Turn the choice into tests

For each platform, document redirect URI, OS association mechanism, browser behavior, PKCE method, state storage, [issuer validation](https://www.devobs.io/articles/oauth-mix-up-issuer-validation/), and fallback. Test a malicious app claiming the custom scheme, a wrong HTTPS association, a changed loopback port, duplicate callbacks, stale state, and a callback from another issuer.

Choose one shipping client and verify its registered redirect against the exact runtime value. If it uses a custom scheme on a platform that supports verified HTTPS links, schedule the claimed-link migration and keep both redirects separated during rollout.

## Source references

- <https://www.rfc-editor.org/rfc/rfc8252>
- <https://www.rfc-editor.org/rfc/rfc9700>
