Open Redirect
Also Known As
unvalidated redirect
open redirector
URL redirect vulnerability
TL;DR
A redirect destination taken from user input can send victims to attacker-controlled sites, enabling phishing.
Explanation
An open redirect lets an attacker craft a URL on your trusted domain that immediately redirects to a malicious site. Because the initial URL appears legitimate (e.g. yourbank.com/login?next=evil.com), victims are more likely to click it. Attackers use open redirects in phishing campaigns and OAuth token theft. Mitigation: validate redirect targets against an explicit allowlist of permitted paths, or restrict to relative URLs only.
How It's Exploited
GET /login?next=https://evil.com
# After login, user is silently redirected to phishing site
# After login, user is silently redirected to phishing site
Common Misconception
✗ Open redirects are low severity because they just redirect users. They are routinely chained with phishing (trusted domain in the URL), OAuth redirect_uri bypass, and SSRF — making them a common link in higher-severity attack chains.
Why It Matters
An open redirect lends your trusted domain to phishing campaigns — the victim sees a legitimate URL before being redirected to a malicious site.
Common Mistakes
- Using $_GET['redirect'] or $_GET['next'] directly in header('Location: ...') without validation.
- Validating that the URL starts with your domain using strpos() — trivially bypassed with your-domain.evil.com.
- Allowing protocol-relative URLs (//evil.com) which browsers interpret as full redirects.
- Forgetting that JavaScript redirects (window.location) are equally exploitable if fed from user input.
Code Examples
✗ Vulnerable
// Redirects to any URL the user provides
$url = $_GET['next'];
header('Location: ' . $url);
✓ Fixed
// Allowlist approach
$allowed = ['/dashboard', '/profile', '/orders'];
$next = $_GET['next'] ?? '/dashboard';
$target = in_array($next, $allowed, true) ? $next : '/dashboard';
header('Location: ' . $target);
// Or validate it's the same host
$parsed = parse_url($next);
if (!empty($parsed['host'])) { $next = '/dashboard'; } // reject absolute URLs
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
20
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 8
Ahrefs 3
Google 2
ChatGPT 2
Perplexity 1
Also referenced
How they use it
crawler 14
crawler_json 2
Related categories
⚡
DEV INTEL
Tools & Severity
🟡 Medium
⚙ Fix effort: Low
⚡ Quick Fix
Never redirect to a URL taken from user input; use an allowlist of permitted destinations or internal path-only redirects
📦 Applies To
PHP 5.0+
web
🔗 Prerequisites
🔍 Detection Hints
header('Location: '.$_GET[ or redirect($_GET['url'] or redirect($_GET['next']
Auto-detectable:
✓ Yes
semgrep
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: Function
Tests: Update
CWE-601