Unvalidated Redirects in OAuth Callback Flows

OAuth 2.0 relies on redirection to pass authorization codes and access tokens between identity providers and client applications. When applications fail to properly validate the redirect_uri parameter during the authorization callback flow, malicious actors can manipulate the destination endpoint. This article examines the critical risks associated with unvalidated OAuth redirect URLs—including authorization code theft, account hijacking, and phishing—and outlines the essential defensive measures developers must implement to secure their authentication architecture.

How Unvalidated OAuth Callbacks Occur

During the standard OAuth authorization code flow, the client application directs the user to an authorization server with a query parameter such as redirect_uri=https://example.com/callback. Once the user authenticates and grants consent, the authorization server sends the user’s browser back to that URI with a temporary authorization code appended to the query string.

Vulnerabilities arise when the authorization server or client application performs weak or incomplete validation on this parameter. Common implementation flaws include:

  • Wildcard Matching: Allowing loose patterns such as https://*.example.com/callback or https://example.com/*, enabling attackers to redirect to arbitrary subdomains or open redirect paths.
  • Permissive Regular Expressions: Using flawed regex that permits domain spoofing, such as matching https://example.com.attacker.com or https://attacker.com/?example.com.
  • Path Traversal: Accepting relative paths that bypass intended callback directories (e.g., https://example.com/oauth/callback/../../logout).
  • Missing Whitelists: Relying entirely on user-supplied parameters without comparing them against pre-registered, static endpoints.

Major Dangers of Weak Redirect Validation

1. Account Takeover via Authorization Code Theft

The most severe outcome of an unvalidated redirect is full account takeover. If an attacker crafts a malicious authorization link with a controlled destination (e.g., redirect_uri=https://attacker.com/log), and an authenticated user follows it, the identity provider sends the authorization code directly to the attacker’s server.

In flows where the client secret is not required or public clients are used without PKCE, the attacker can immediately exchange this code for an access token and refresh token, fully compromising the user's session.

2. Credential Leakage via Open Redirect Chains

Even if the authorization server enforces strict domain matching, an internal open redirect anywhere on that allowed domain can be chained to leak credentials.

For instance, if the allowed URI is https://example.com/oauth/callback, but that endpoint redirects to a secondary URL controlled by a query parameter (such as https://example.com/oauth/callback?next=https://attacker.com), the authorization code or access token fragment can be forwarded to the attacker via the HTTP Referer header or direct URL forwarding.

3. Advanced Phishing Campaigns

OAuth-based phishing attacks exploit the implicit trust users place in reputable identity providers like Google, GitHub, or Microsoft. Because the initial login and consent prompt appear on the legitimate provider's domain, security warnings are not triggered. Once consent is granted, the user is redirected to a malicious clone of the application hosted on the attacker's server, making subsequent data harvesting highly effective.

4. Bypassing Cross-Site Request Forgery (CSRF) Defenses

Unvalidated redirects can compromise the integrity of the OAuth state parameter. Attackers can bind a victim's external account to the attacker's local account profile by manipulating redirect flows and injecting authorization codes, leading to persistent account access and session fixation vulnerabilities.

Best Practices for Mitigation

To eliminate the risks of unvalidated redirect URLs in OAuth implementations, follow these requirements:

  • Enforce Exact String Matching: Avoid wildcards, subdomains, and regex matching. The authorization server should match the supplied redirect_uri character-by-character against a pre-registered whitelist of full URIs.
  • Mandate PKCE (Proof Key for Code Exchange): Implement PKCE (RFC 7636) across all clients, not just mobile or single-page applications. Even if an authorization code is intercepted via an open redirect, an attacker cannot exchange it without the cryptographically generated code verifier.
  • Eliminate Secondary Open Redirects: Audit client callback endpoints to ensure they do not process unvalidated internal redirects (e.g., dynamic return_to or next parameters) after authentication completes.
  • Utilize the state Parameter: Always generate and validate a unique, cryptographically secure, session-bound state token to verify that the response corresponds to an authorization request initiated by the same browser session.