SecureBlockLog inStart a pentest
Vulnerability Repository
MediumAccess Control

Open Redirect

Unvalidated redirect parameters allow attackers to send users from a trusted domain to an arbitrary external URL, enabling phishing and credential harvesting.

CVSS 6.1CWE CWE-601OWASP A01:2021 — Broken Access Control

Description

An open redirect (CWE-601 — URL Redirection to Untrusted Site) occurs when a web application accepts a URL or path as a parameter and redirects the user to that destination without validating that it belongs to an approved set of destinations. The attack exploits the trust users place in the application's domain: the initial link appears to originate from a legitimate, familiar host, but ultimately delivers the user to an attacker-controlled site.

Open redirects are frequently dismissed as low-severity by developers who reason that "the user ends up somewhere else, so what?" In practice, they are highly effective as a phishing delivery mechanism — particularly in credential harvesting campaigns, OAuth token theft, and malware distribution. The value of the vulnerability is the legitimacy borrowed from the trusted domain in the originating link.

OWASP A01:2021 — Broken Access Control includes open redirects because the application is failing to control where it directs users — an authorization decision. Open redirects can also be chained with SSRF vulnerabilities in some architectures, where the redirect is followed by a server-side component.

How It Works

A typical pattern is a login page that preserves the originally requested URL as a next or redirect parameter:

https://app.example.com/login?next=https://evil.com/phishing

After successful authentication, the server executes:

return redirect(request.args.get("next"))

Without validation, the browser is sent to evil.com/phishing. The attacker sends the full URL to a victim. The victim sees app.example.com in the link and trusts it.

Bypass techniques are important to understand because developers often implement naive blocklists:

  • Scheme bypass//evil.com (protocol-relative URL, inherits https:) or javascript: URIs on some older implementations.
  • URL encodinghttps%3A%2F%2Fevil.com may bypass string-match filters.
  • At-sign bypasshttps://app.example.com@evil.com — the browser navigates to evil.com, as the username portion is app.example.com.
  • Subdomain bypasshttps://evil.com.app.example.com passes a suffix check for app.example.com if the check is not anchored to the end of the trusted domain.
  • Whitespace and null bytes — some parsers normalize %09 (tab) or %0d%0a (CRLF) in URLs differently than application-level filters.

OAuth phishing via open redirect is a high-severity chain. If the OAuth authorization endpoint at a trusted identity provider accepts a redirect URI via an open redirect on the relying party domain, an attacker can steal authorization codes:

https://auth.example.com/oauth/authorize
  ?client_id=app
  &redirect_uri=https://app.example.com/callback?next=https://evil.com
  &response_type=code

If the callback handler follows the next redirect after processing the OAuth code, the attacker can intercept the code in the Referer header on their evil site.

Impact

  • Phishing and credential harvesting — victims are sent to a convincing replica login page from a trusted-looking link.
  • OAuth token theft — authorization codes or access tokens leak to an attacker via chained OAuth redirect abuse.
  • Malware delivery — users are redirected to drive-by download sites or exploit kits from a trusted domain link.
  • Reputation damage — the organization's domain appears in phishing URLs, damaging brand trust and triggering domain blocklisting.
  • Session token leakage — if the token is appended to the redirect URL as a query parameter, it may be exposed in server logs on the destination site via the Referer header.

Detection

  1. Identify all redirect parameters — search for parameters named next, redirect, url, return, returnUrl, goto, dest, destination, redir, target, and callback. Test in both GET query strings and POST bodies.
  2. Test with a direct external URL — supply https://example.com (a benign external host) and confirm whether the server redirects there. A Location: https://example.com header in a 3xx response confirms the vulnerability.
  3. Test bypass techniques — if the base payload is blocked, try //example.com, https://example.com@app.target.com, https://app.target.com.example.com, URL-encoded variants, and whitespace injection.
  4. Check for OAuth chaining — identify OAuth callback endpoints and test whether an open redirect on the callback path can be leveraged to leak authorization codes to an external host.
  5. Test mobile app deep links — iOS and Android deep link handlers that accept URL parameters for navigation can be vulnerable to the same redirect abuse as web parameters.

Remediation

Use an allowlist of permitted redirect destinations. The most reliable fix is to maintain a server-side list of approved redirect URLs or domains, and reject any redirect target that does not match:

ALLOWED_REDIRECTS = {"/dashboard", "/profile", "/settings"}

def safe_redirect(next_url):
    if next_url not in ALLOWED_REDIRECTS:
        return redirect("/dashboard")  # Default safe destination
    return redirect(next_url)

Use indirect redirect maps. Rather than accepting a URL, accept an opaque key that maps to a URL server-side (?next=1/dashboard, ?next=2/profile). Users can never influence the destination URL directly.

Validate that the redirect target is on the same origin. If redirects to external sites are never intentional, reject any next value that contains a scheme (https://, //) or a different host. Use urllib.parse or equivalent to parse and compare the host component.

Avoid appending tokens or sensitive parameters to redirect URLs. Ensure that OAuth tokens, session identifiers, and other sensitive values are never appended as query parameters to redirect URLs, as they may leak via Referer headers.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping