TL;DR
Open redirects happen when your site redirects users based on a URL parameter without validation. Attackers create links that look like your site but redirect to malicious pages. Fix by validating redirect URLs are relative paths or belong to your allowed domains.
What Is an Open Redirect?
An open redirect vulnerability allows attackers to craft URLs on your domain that redirect users to external malicious sites. Since the link appears to be from your trusted site, users are more likely to click it.
// Attacker creates this phishing link:
// https://yoursite.com/login?redirect=https://evil.com/fake-login
// Your vulnerable code:
app.get('/login', (req, res) => {
// After login, redirect to the URL parameter
const redirectUrl = req.query.redirect;
res.redirect(redirectUrl); // VULNERABLE!
});
Why It's Dangerous
- Users trust links from your domain
- Used in phishing to steal credentials
- Can bypass email/URL filters
- OAuth attacks using redirect_uri manipulation
How to Fix Open Redirects
function isValidRedirect(url) {
// Allow relative URLs
if (url.startsWith('/') && !url.startsWith('//')) {
return true;
}
// Allow specific domains
try {
const parsed = new URL(url);
const allowedHosts = ['yoursite.com', 'app.yoursite.com'];
return allowedHosts.includes(parsed.host);
} catch {
return false;
}
}
app.get('/login', (req, res) => {
const redirectUrl = req.query.redirect || '/dashboard';
if (!isValidRedirect(redirectUrl)) {
return res.redirect('/dashboard'); // Safe default
}
res.redirect(redirectUrl);
});
Is open redirect a serious vulnerability?
It's medium severity on its own, but it enables more serious attacks like phishing and OAuth token theft. It's often used as a stepping stone in more complex attacks.
How do I handle OAuth redirect_uri?
Validate that redirect_uri exactly matches a pre-registered callback URL. Don't allow partial matches or wildcards in production.