Safeguard
Security Guides•

React Native deep links and OAuth: why PKCE is required

Custom URL scheme deep links can be hijacked by another app. Learn why React Native sign in flows need PKCE and what never to put inside a link.

Safeguard Security Team
3 min read

A custom scheme deep link such as app://products/1 is not a secure channel, because another app can register the same scheme and receive the link. Never put tokens in one. For OAuth sign in, use the authorization code flow with PKCE so an intercepted code is useless alone.

The problem with custom schemes

The React Native security guide explains that URL schemes have no central registry. A malicious app can claim the same scheme and intercept whatever the link carries. Android shows a chooser when more than one app can handle a link, which gives the user a chance to notice. On iOS, the guide says the system picks for the user, and since iOS 11 it uses first come first served, which can still be abused.

So a deep link is user input from an untrusted source. Treat it like any other.

What to do with deep links

  • Never send tokens, passwords or personal data inside a link.
  • Validate every path and parameter before acting, and ignore unknown ones.
  • Do not let a link trigger a sensitive action, such as a payment, without an in app confirmation after authentication.
  • Prefer universal links on iOS. The guide names them as the secure way to link to in app content.
  • On Android, verified app links serve the same purpose. The React Native guide does not cover them, so check the Android documentation for setup.

Why OAuth needs PKCE

In OAuth 2, the identity provider redirects back to your app with a verification code that the app exchanges for a token. On the web, the redirect target is a unique URL. In a mobile app, the redirect often uses a custom scheme, which another app might also claim. The guide says to add PKCE.

How PKCE works, in plain terms:

  1. The app creates a random code verifier and keeps it in memory.
  2. It sends a hash of the verifier, the code challenge, with the authorization request.
  3. When exchanging the code, the app sends the original verifier.
  4. The provider checks that the verifier matches the earlier hash before issuing a token.

A stolen code without the verifier cannot be exchanged. The guide mentions react-native-app-auth, which wraps the native AppAuth libraries and supports PKCE if your provider does. Confirm your provider supports it, and turn it on.

Testing

Install a second test app that registers your scheme and logs incoming links. If it receives anything sensitive, your flow is wrong.

Quick check

Does using HTTPS in the link fix the interception problem?

Custom schemes are not HTTPS links. Use verified web links where possible, and use PKCE for the OAuth redirect either way.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.