Chương 19: Open Redirect
Khái niệm
Open Redirect là lỗ hổng cho phép hacker redirect người dùng từ trang web tin cậy đến trang web tùy ý. Thường dùng để:
- Phishing: redirect đến clone site
- SSRF bypass (chương 15)
- OAuth redirect bypass (chương 7)
Mức độ nguy hiểm: Thấp-Trung bình (standalone) nhưng cao khi kết hợp với các lỗ hổng khác.
Cách hoạt động
# Vulnerable code: redirect sau login
@app.route('/login')
def login():
next_url = request.args.get('next') # Từ user input
if authenticate(request.form):
return redirect(next_url) # Redirect đến URL do user chỉ định
# Normal: /login?next=/dashboard → redirect đến /dashboard
# Attack: /login?next=https://phishing.com → redirect đến phishing site
Bypass Validation
# Nếu server check "next phải chứa example.com":
# /login?next=https://example.com.evil.com → có "example.com"!
# Nếu server check "next phải bắt đầu bằng /":
# /login?next=//evil.com → // là protocol-relative URL!
# → Browser redirect đến: https://evil.com (hoặc http://)
# Encode:
/login?next=%2F%2Fevil.com
/login?next=https:%2F%2Fevil.com
# CRLF injection trong redirect
/login?next=/dashboard%0d%0aLocation:%20https://evil.com
Kịch bản tấn công: SSRF via Open Redirect
SSRF payload bị block trực tiếp:
{"url": "http://169.254.169.254/"} → BLOCKED (IP blocklist)
Bypass qua open redirect:
1. example.com có open redirect: /redirect?url=...
2. SSRF payload: {"url": "https://example.com/redirect?url=http://169.254.169.254/"}
3. App fetch example.com → 302 redirect → 169.254.169.254
4. Nếu app follow redirects → SSRF bypass!
Phòng chống
from urllib.parse import urlparse
def safe_redirect(next_url: str, default: str = '/dashboard') -> str:
if not next_url:
return default
parsed = urlparse(next_url)
# Chỉ cho phép relative paths hoặc same origin
if parsed.scheme or parsed.netloc:
# External URL → không redirect
return default
# Chỉ cho phép paths bắt đầu bằng /
if not next_url.startswith('/'):
return default
# Chặn //evil.com
if next_url.startswith('//'):
return default
return next_url
# Hoặc: Dùng whitelist
ALLOWED_REDIRECTS = {'/dashboard', '/profile', '/settings'}
def validate_redirect(next_url: str) -> str:
if next_url in ALLOWED_REDIRECTS:
return next_url
return '/dashboard'
Tóm tắt
- Open redirect: redirect user đến URL tùy ý → phishing, SSRF bypass, OAuth bypass.
//evil.comlà URL hợp lệ (protocol-relative).- Phòng chống: chỉ allow relative paths, reject external URLs, dùng whitelist.