Open Redirect is a vulnerability where an application accepts a user-controlled URL parameter and redirects users to that URL without proper validation. Attackers exploit this to redirect victims to malicious sites, making phishing attacks more convincing.
Applications often redirect users after certain actions (login, logout, form submission). When the redirect destination comes from user input without validation, attackers can craft links that appear to point to a trusted domain but redirect to a malicious site.
// Vulnerable redirect implementations
https://trusted.com/redirect?url=https://evil.com
https://trusted.com/login?next=https://evil.com
https://trusted.com/go?to=https://evil.com/phish
https://trusted.com/out?link=//evil.com
// Vulnerable server code (Node.js)
app.get('/redirect', (req, res) => {
res.redirect(req.query.url); // No validation!
});
# Protocol-relative URLs
//evil.com
# URL encoding
https://trusted.com/redirect?url=https%3A%2F%2Fevil.com
# Using @ to fake domain
https://trusted.com@evil.com/page
# Backslash confusion (Windows/some parsers)
https://trusted.com/redirect?url=https:/\evil.com
# Data URI (in some contexts)
data:text/html,<script>location='https://evil.com'</script>
# Domain confusion
https://trusted.com.evil.com
https://trusted-com.evil.com
https://eviltrusted.com
# Whitespace/null byte injection
https://trusted.com/redirect?url=https://evil.com%00.trusted.com
# Double URL encoding
https://trusted.com/redirect?url=%2568ttps://evil.com
javascript:alert(1) in some implementations# OAuth flow with open redirect
1. Attacker crafts: https://trusted.com/oauth/callback?redirect=/redirect?url=https://evil.com
2. User authenticates via OAuth
3. OAuth provider redirects to trusted.com with token in fragment
4. Trusted.com's open redirect sends user to evil.com
5. Token may leak via Referer header or if preserved in fragment
// Safe redirect with allowlist
const allowedHosts = ['trusted.com', 'sub.trusted.com'];
function safeRedirect(url) {
try {
const parsed = new URL(url, 'https://trusted.com');
if (allowedHosts.includes(parsed.hostname)) {
return parsed.href;
}
} catch (e) {}
return '/'; // Default to home
}
// Or: Only allow relative paths
function isRelativePath(url) {
return url.startsWith('/') && !url.startsWith('//');
}