OAUTH2_REDIRECT_URI_PATH_TRAVERSAL security auth_error ai_generated true

OAuth2 redirect_uri path traversal allows open redirect to attacker domain

ID: security/oauth2-redirect-uri-path-traversal

Also available as: JSON · Markdown · 中文
78%Fix Rate
85%Confidence
1Evidence
2024-03-12First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Spring Security OAuth2 2.5.0 active
OAuth2 Proxy 7.4.0 active
Keycloak 21.0.0 active
Apache Oltu 1.0.2 active

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.

generic

中文

OAuth2提供者仅通过前缀匹配验证redirect_uri,允许攻击者使用注册的回调URL并附加路径遍历后缀如../evil.com重定向到外部域名。

Official Documentation

https://datatracker.ietf.org/doc/html/rfc6749#section-10.6

Workarounds

  1. 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()'
    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. 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'
    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. 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.
    Use a whitelist of allowed hosts and enforce that redirect_uri's host matches exactly. Combine with path validation to prevent open redirect.

中文步骤

  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()'
  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'
  3. 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

Common approaches that don't work:

  1. 95% fail

    Does not fix the root cause; attacker can still use path traversal on any registered URI.

  2. 80% fail

    Attackers can use URL encoding (%2e%2e%2f) or double encoding to bypass simple character blacklists.

  3. 100% fail

    Does not address the validation logic; timeout is unrelated to redirect URI validation.