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/callbackorhttps://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.comorhttps://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_uricharacter-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_toornextparameters) after authentication completes. - Utilize the
stateParameter: Always generate and validate a unique, cryptographically secure, session-boundstatetoken to verify that the response corresponds to an authorization request initiated by the same browser session.