Overview
An open redirect is a vulnerability in which a web application uses attacker-supplied input to construct a destination URL for an HTTP redirect response (status codes 301, 302, 303, 307, or 308) without verifying that the destination is within a trusted set of locations. Because the redirect originates from a legitimate, trusted domain, victims and security controls (email filters, browser warnings) are less likely to flag the initial link as malicious.
Sensagraph automatically detects open redirect vulnerabilities by probing redirect parameters for external destination acceptance.
How it works
Open redirects arise whenever user-controlled data is passed directly into a redirect mechanism. The typical attack chain is:
- Craft the URL: The attacker identifies a redirect parameter on a trusted site, e.g.
https://example.com/login?next=https://evil.com/phish. - Distribute the link: The attacker sends the crafted URL via email, social media, or chat. The visible domain is
example.com, making the link appear legitimate. - Victim clicks and is redirected: The server reads the
nextparameter without validation and issues an HTTP 302 response tohttps://evil.com/phish. - Attacker achieves goal: The victim arrives at a phishing page, credential harvester, or malware download, believing they were redirected by a trusted site.
Beyond phishing, open redirects are commonly chained with other vulnerabilities:
- OAuth token theft: When an OAuth 2.0 authorization server does not strictly validate
redirect_uri, an open redirect on the client application can be used to exfiltrate authorization codes or access tokens via theRefererheader or URL fragment leakage. - SSRF facilitation: In some architectures, a server-side redirect to an attacker-controlled URL can enable Server-Side Request Forgery by causing the server itself to fetch the attacker's URL.
- Security control bypass: Allowlist-based URL filters that check only the initial URL (before following redirects) can be bypassed using an open redirect on a trusted domain.
- Cross-Site Scripting (XSS) via
javascript:URIs: If the redirect destination is not sanitized, some implementations acceptjavascript:scheme URLs, leading to XSS when the browser processes the redirect target.
Common vulnerable code patterns include:
- PHP:
header("Location: " . $_GET['url']); - Java/Spring:
return "redirect:" + request.getParameter("next"); - Node.js/Express:
res.redirect(req.query.returnTo); - Python/Django:
return HttpResponseRedirect(request.GET.get('next'))without validation
Business impact
While open redirects are often rated medium severity in isolation, the practical business impact can be significant:
- Phishing and credential theft: Users deceived by a redirect from a trusted domain may submit credentials to an attacker-controlled site, leading to account takeover.
- Brand and reputational damage: Customers associate the phishing attack with the legitimate brand, eroding trust even when the organization is a victim rather than the cause.
- Regulatory and compliance exposure: Credential theft facilitated through the organization's own infrastructure may trigger breach notification obligations under GDPR, HIPAA, PCI-DSS, or similar frameworks.
- Token exfiltration in OAuth flows: A successful OAuth redirect attack can lead to full account compromise without requiring the user's password.
- Malware distribution: Attackers may redirect users to drive-by download pages, making the organization's domain an unwitting vector for malware delivery.
How to fix it
- Avoid user-controlled redirect destinations entirely: The most robust defense is to redesign flows so the redirect destination is never derived from user input. Instead, use server-side mappings (e.g., a numeric action ID that maps to a hardcoded URL).
- Implement a strict allowlist: If a dynamic redirect is necessary, validate the destination against a hardcoded allowlist of permitted domains or paths. Reject any destination not on the list.
- Example (Python):
ALLOWED = {'https://example.com/dashboard', 'https://example.com/profile'}; if url not in ALLOWED: url = '/default'
- Example (Python):
- Validate relative paths only: Restrict accepted redirect values to relative paths (starting with
/but not//) within the same origin. Reject absolute URLs with a scheme and host component entirely. - Enforce strict
redirect_urimatching in OAuth: Per RFC 6749 §3.1.2.2, authorization servers MUST require an exact match (or registered prefix match) of theredirect_uri. Do not perform open matching or partial URL comparison. - Apply the
javascript:URI blocklist: Explicitly reject any redirect destination whose scheme is nothttporhttps. - Warn users before external redirects: If redirecting outside the application's own domain is a necessary business feature, display an interstitial warning page informing the user they are leaving the site, rather than silently forwarding them.
- Add automated test coverage: Include open redirect test cases in CI/CD pipelines to prevent regressions when redirect logic changes.