Stop 4 of 42 · The Front Door · Open redirect

The greeter who walks you anywhere

The bank’s greeter walks visitors to wherever a slip says, such as “after you sign in, go to…”. He never checks the address. Mallory writes the address of a fake branch on the slip, and Alice follows a greeter she trusts straight to a trap.

Severity Medium–HighCategory Auth WeaknessThe Front DoorSources checked 25 Oct 2026

Watch it happen

Play it as

Alice follows a link that starts at the real bank. The greeter walks her to the fake branch named on the slip.

Arrival

Alice walks up to the real bank’s front door, where the greeter takes people where they need to go.

1 / 5

In bank terms and app terms

In the bankIn your app
Greeter walking visitorsYour redirect after login or on a link, such as ?next= or ?redirect_to=
The address on the slipA URL parameter the user, or an attacker’s link, controls
Fake branchA phishing page that looks like your site
Only addresses inside the bankAllowing only same-origin paths, or a short allowlist of full URLs

Are you exposed?

You might be exposed if…
  • You redirect to a value from the URL, like ?next=, ?redirect=, ?return_url= or ?callback=.
  • You “validate” by checking that the value starts with /, or only that it contains your domain.
  • Your login or OAuth callback sends people back to whatever URL they came from without checking it.
What to do about it
  1. Redirect only to relative paths on your own site, or to a fixed allowlist of known URLs.
  2. Resolve the value with new URL(value, yourOrigin) and check the result’s origin equals yours. A simple starts-with check can be fooled.
  3. If it fails the check, fall back to / and never to the supplied address.

Track these in your to-do list →

It has happened to real companies

Real-world breaches

Google (ongoing) — Google's redirect endpoints (google.com/url?q=...) have been repeatedly abused in phishing campaigns to make malicious links appear to originate from google.com.

What it looks like in code

// GOOD: Resolve against your own origin, then compare origins.
// A starts-with check on "http" or "//" is not enough: browsers treat a
// backslash as a slash, so "/\/evil.com" slips past it.
const redirectTo = searchParams.get("redirect_to") || "/"
const target = new URL(redirectTo, request.url)
if (target.origin !== new URL(request.url).origin) {
  return NextResponse.redirect(new URL("/", request.url))
}
return NextResponse.redirect(target)

Ask your AI tool to fix it

Paste this into Cursor, Claude, Lovable, Bolt or whatever you build with.

Prompt
Find every place this app redirects using a value from the request (next, redirect, redirect_to, return_url, callback). For each one, resolve the value against our own origin with new URL(value, origin) and only redirect if the resulting origin equals ours. Otherwise redirect to "/". Do not rely on startsWith checks, because backslashes and protocol-relative URLs can bypass them. List what you changed.

Where this comes from

The facts, figures and fixes on this page were checked against these sources on 25 Oct 2026. They are linked so you can check for yourself.

Spot a mistake or something out of date? Report a correction · How these guides are made and checked

Go deeper in isitsecure

The free, open-source scanner checks for most of the problems in these guides.