# OAuth2重定向URI路径遍历允许开放重定向到攻击者域名

- **ID:** `security/oauth2-redirect-uri-path-traversal`
- **领域:** security
- **类别:** auth_error
- **错误码:** `OAUTH2_REDIRECT_URI_PATH_TRAVERSAL`
- **验证级别:** ai_generated
- **修复率:** 78%

## 根因

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

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| Spring Security OAuth2 2.5.0 | active | — | — |
| OAuth2 Proxy 7.4.0 | active | — | — |
| Keycloak 21.0.0 | active | — | — |
| Apache Oltu 1.0.2 | active | — | — |

## 解决方案

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

## 无效尝试

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