CodePark/ questions / Links, redirects & tabnabbing
START PRACTICINGPRACTICE
Frontend question · Frontend security › Links, redirects & tabnabbing

What is an open redirect? How can a ?returnTo= parameter on an SPA login page be abused, and how do you validate it?

An open redirect is when your app sends the user to a URL taken from input, without checking it.

How attackers use ?returnTo=:

  • Phishing: the link https://app.example/login?returnTo=https://evil.example starts with your trusted domain. After login, the user lands on a fake "session expired, log in again" page.
  • XSS: if the code does location.href = returnTo, a javascript: URL runs script in your origin.
  • Token theft: if the redirect sits on a path that OAuth allows as a redirect_uri, it can forward codes or tokens to the attacker.

How to validate:

  • Parse it: const url = new URL(returnTo, location.origin).
  • Require url.origin === location.origin.
  • Navigate to url.pathname + url.search + url.hash, not to the raw string.
  • Or don't put the URL in the link at all. Save it in sessionStorage before the login starts.
  • Or accept only names from a list, such as returnTo=billing.

Don't check with startsWith("/") or a regex. Values like //evil.example and /\evil.example pass those checks, but browsers treat them as other sites.

  • An open redirect sends users to a URL from input without checking it.
  • Attackers use it for phishing links that start with your domain.
  • A javascript: value can turn the redirect into XSS.
  • Parse with new URL and require the same origin before you navigate.
  • Simple checks like startsWith("/") miss //evil.example.