The short version
An open redirect happens when your application takes a URL from user input (usually a query parameter) and sends the user there without checking if the destination is safe. Attackers abuse this to send users to phishing sites, malware, or token-stealing pages, all while the link looks like it comes from your trusted domain.
It's tracked as CWE-601: URL Redirection to Untrusted Site.
How it works
Many apps have a redirect feature. After login, you want to send the user back to the page they came from:
https://yourapp.com/login?redirect=/dashboard
That's fine when the redirect is /dashboard. But what if an attacker crafts this link?
https://yourapp.com/login?redirect=https://evil-site.com/steal-credentials
If your code blindly redirects to whatever is in the redirect parameter, the user lands on the attacker's page. From the user's perspective, they clicked a link to yourapp.com. They have no reason to suspect anything.
Why attackers love it
Phishing. The link starts with your domain. Email filters and link scanners see your legitimate domain and let it through. Users see your domain and trust it. The redirect to the phishing page happens after the click.
OAuth token theft. If your OAuth flow uses a redirect URI parameter and doesn't validate it strictly, an attacker can steal authorization codes by redirecting them to their own server.
Chaining with other vulnerabilities. Open redirects are often used as a building block for more complex attacks. The OWASP Unvalidated Redirects guide covers several attack chains.
Common patterns
Login redirects:
// DANGEROUS: redirects to whatever is in the query string
const redirectUrl = req.query.redirect;
res.redirect(redirectUrl);
Logout redirects:
https://yourapp.com/logout?return_to=https://evil.com
Link shorteners and tracking URLs:
https://yourapp.com/go?url=https://evil.com
Any place where your app takes a URL from user input and sends the user there is a potential open redirect.
How to prevent it
Use an allowlist. Only redirect to URLs that match a list of trusted domains or paths:
const allowedHosts = ['yourapp.com', 'docs.yourapp.com'];
const redirectUrl = new URL(req.query.redirect, 'https://yourapp.com');
if (allowedHosts.includes(redirectUrl.hostname)) {
res.redirect(redirectUrl.toString());
} else {
res.redirect('/');
}
Use relative paths only. If your redirect only needs to go to pages on your own site, reject any URL that starts with http://, https://, or //:
const redirect = req.query.redirect;
if (redirect && redirect.startsWith('/') && !redirect.startsWith('//')) {
res.redirect(redirect);
} else {
res.redirect('/');
}
Don't pass URLs as query parameters at all. Use a lookup key instead:
/login?redirect=dashboard (maps to /dashboard in your code)
This eliminates the attack entirely because users can't control the destination URL.
Watch out for bypasses
Attackers are creative. Some bypass techniques:
//evil.com(protocol-relative URL, treated as external)https:evil.com(some parsers accept this)\/\/evil.com(backslash tricks on some platforms)- URL-encoded characters:
%2F%2Fevil.com
Always parse the URL properly using your language's URL parser, then validate the hostname. Don't rely on string matching.
Check your site
Want to know if your site has this issue? Scan it now and find out in 60 seconds.
Frequently Asked Questions
- What is an open redirect?
- An open redirect is when your application takes a URL as a parameter and redirects the user to it without validation. Attackers abuse this to redirect users to phishing or malware sites using your trusted domain.
- Is an open redirect a serious vulnerability?
- On its own, it's medium severity. But it's powerful in combination with phishing. Users trust your domain, so they click links that look legitimate. It's also used to steal OAuth tokens.
- How do I prevent open redirects?
- Validate redirect URLs against an allowlist of trusted domains. Never blindly redirect to user-supplied URLs.
Your AI writes the code. We find what it missed.
Paste your URL. Security audit in 60 seconds.
Scan my app