Athena Wiki
Web ExploitationAuthentication

Open Redirect & Unvalidated Forwards

webintermediate

Exploit open redirects in CTF web - filter bypasses, OAuth and SSO chains, and SSRF validation bypass via trusted-domain redirects.

webopen-redirecturl-redirectionoauthphishingssrfcwe-601

Open Redirect & Unvalidated Forwards

Open redirect means the application sends the user to a URL taken from attacker-controlled input without strict validation (CWE-601). The victim clicks a trusted hostname, but ends up on attacker content - classic phishing. In CTF, redirects are also chain primitives: OAuth redirect_uri tricks, SSO, and SSRF “hop through” trusted domains.

OWASP: Open Redirect, Unvalidated Redirects and Forwards Cheat Sheet.

Typical Parameters

ParameterContext
next, return, returnUrl, continueAfter login / logout
url, redirect, redir, gotoMarketing “exit” links, SSO
redirect_uriOAuth / OIDC (must match exact registered URI - misconfigurations happen)

Example:

https://trusted.example/login?next=https://evil.example/phish

Bypass Techniques

Never validate URLs with naive string checks (startsWith("https://trusted.com")). Parsers disagree on edge cases.

TechniquePayload idea
Protocol-relative//evil.com
Userinfohttps://trusted.com@evil.com/ (parser-dependent)
Backslashhttps://trusted.com\evil.com (older IE / odd parsers)
Encoding%2f%2fevil.com, double encoding
Tab / CRLF\t, %0d%0a if reflected into Location
Path-only then server joins badly/\\evil.com

Use your language’s URL parser (urllib.parse, URL(), java.net.URI) and enforce:

  • Scheme is https (if required)
  • Host is in an allowlist
  • Path starts with / and stays in-app or map IDs server-side

Attack Chains in CTF

OAuth / OpenID redirect_uri

If the server allows prefix match or wildcard, you may redirect the authorization code to an attacker-controlled endpoint. Always test exact vs substring registration.

SSRF + redirect

Backend fetches https://trusted.com/... (allowed host). trusted.com 302 redirects to http://169.254.169.254/. If the HTTP client follows redirects, you may hit metadata. Mitigation: do not follow redirects or re-validate each hop (SSRF).

Filter bypass for “same site”

Some apps allow https://trusted.com.evil.com when they meant exact host - depends on parser.

Vulnerable vs Fixed (Sketch)

Vulnerable (Python / Flask-style)

from flask import redirect, request

@app.route("/go")
def go():
    url = request.args.get("url")
    return redirect(url)  # NEVER

Safer: allowlist host after parsing

from urllib.parse import urlparse

ALLOWED = {"trusted.example"}

@app.route("/go")
def go():
    url = request.args.get("url", "/")
    p = urlparse(url)
    if p.scheme in ("http", "https") and p.hostname in ALLOWED:
        return redirect(url)
    return redirect("/")

Best for “only in-app”: only allow paths

if url.startswith("/") and not url.startswith("//"):
    return redirect(url)

Checklist

  • Map every redirect, next, return, url parameter
  • Try external URLs and protocol-relative //
  • Try encoding and slashes variants
  • If OAuth exists, test redirect_uri parsing end-to-end
  • If SSRF exists, test 302 from “allowed” host to internal IP
  • Confirm whether Location header reflects newline injection (historical)

Last updated on

On this page