An open redirect happens when your app redirects to a URL taken from user input without checking it. An attacker uses a link on your trusted domain that quietly forwards the victim to a site they control, which is powerful for phishing. The fix is to only redirect to destinations you have approved.
Why it's a problem
The link looks like it belongs to you, so users and email filters trust it, then it lands them on an attacker's login page that harvests credentials. Open redirects are also chained into OAuth and SSO attacks to steal tokens. The danger is the abuse of your domain's trust, not a crash.
The pattern
// redirects anywhere the user says
app.get("/go", (req, res) => res.redirect(req.query.url));The fix
const allowedPaths = new Set(["/dashboard", "/settings"]);
app.get("/go", (req, res) => {
const target = req.query.url;
// only allow known internal paths, never arbitrary URLs
if (typeof target === "string" && allowedPaths.has(target)) {
return res.redirect(target);
}
res.redirect("/");
});Why AI tools write this
A redirect that reads the destination from a query parameter is the direct way to build a 'return to where you came from' flow, so it is a natural completion. It behaves correctly for your own links, and only becomes a redirect-anywhere when an attacker supplies the value.
The quick fix
- Redirect only to an allowlist of known internal paths.
- Reject absolute URLs and anything pointing to another host.
- If you must round-trip a return URL, validate it is a relative path first.