# OAuth2 redirect_uri path traversal allows open redirect to attacker domain

- **ID:** `security/oauth2-redirect-uri-path-traversal`
- **Domain:** security
- **Category:** auth_error
- **Error Code:** `OAUTH2_REDIRECT_URI_PATH_TRAVERSAL`
- **Verification:** ai_generated
- **Fix Rate:** 78%

## Root Cause

OAuth2 provider validates redirect_uri only by prefix match, allowing attacker to use a registered callback URL with a path traversal suffix like ../evil.com to redirect to an external domain.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Spring Security OAuth2 2.5.0 | active | — | — |
| OAuth2 Proxy 7.4.0 | active | — | — |
| Keycloak 21.0.0 | active | — | — |
| Apache Oltu 1.0.2 | active | — | — |

## Workarounds

1. **Use exact URI matching instead of prefix matching: verify that the redirect_uri exactly matches one of the registered URIs, including path and query parameters. Example in Python with Flask-OAuthlib: 'if redirect_uri not in client.redirect_uris: raise InvalidRedirectURI()'** (92% success)
   ```
   Use exact URI matching instead of prefix matching: verify that the redirect_uri exactly matches one of the registered URIs, including path and query parameters. Example in Python with Flask-OAuthlib: 'if redirect_uri not in client.redirect_uris: raise InvalidRedirectURI()'
   ```
2. **Normalize the redirect_uri before validation: decode URL encoding, resolve path traversals, and reject if the normalized URI does not start with the registered base URI. Example: 'from urllib.parse import urlparse, urlunparse; parsed = urlparse(redirect_uri); if '..' in parsed.path: reject'** (88% success)
   ```
   Normalize the redirect_uri before validation: decode URL encoding, resolve path traversals, and reject if the normalized URI does not start with the registered base URI. Example: 'from urllib.parse import urlparse, urlunparse; parsed = urlparse(redirect_uri); if '..' in parsed.path: reject'
   ```
3. **Use a whitelist of allowed hosts and enforce that redirect_uri's host matches exactly. Combine with path validation to prevent open redirect.** (85% success)
   ```
   Use a whitelist of allowed hosts and enforce that redirect_uri's host matches exactly. Combine with path validation to prevent open redirect.
   ```

## Dead Ends

- **** — Does not fix the root cause; attacker can still use path traversal on any registered URI. (95% fail)
- **** — Attackers can use URL encoding (%2e%2e%2f) or double encoding to bypass simple character blacklists. (80% fail)
- **** — Does not address the validation logic; timeout is unrelated to redirect URI validation. (100% fail)
