| タイトル | Casdoor v2.356.0 Open Redirect |
|---|
| 説明 | **Evidence:**
```go
for _, targetUri := range application.RedirectUris {
targetUriRegex := regexp.MustCompile(targetUri)
if targetUriRegex.MatchString(redirectUri) || strings.Contains(redirectUri, targetUri) {
return true
}
}
```
Two critical flaws:
1. `strings.Contains(redirectUri, targetUri)` is a substring match. If an application registers `https://app.example.com/callback`, then `https://evil.com/https://app.example.com/callback` passes validation.
2. `regexp.MustCompile(targetUri)` treats stored redirect URIs as regex patterns. A URI containing `.` matches any character. An entry like `https://example.com` matches `https://exampleXcom.evil.com`.
**Attack scenario:** An attacker constructs an OAuth authorization request with `redirect_uri=https://evil.com/?x=https://app.example.com/callback`. This passes the `strings.Contains` check. The OAuth code/token is then sent to `evil.com`.
**Fix:** Use strict equality or validated prefix matching. Never treat user-configured values as regex patterns. Compare parsed URL components (scheme, host, path) individually:
```go
func (application *Application) IsRedirectUriValid(redirectUri string) bool {
parsedRedirect, err := url.Parse(redirectUri)
if err != nil { return false }
for _, targetUri := range application.RedirectUris {
parsedTarget, err := url.Parse(targetUri)
if err != nil { continue }
if parsedRedirect.Scheme == parsedTarget.Scheme &&
parsedRedirect.Host == parsedTarget.Host &&
strings.HasPrefix(parsedRedirect.Path, parsedTarget.Path) {
return true
}
}
return false
}
``` |
|---|
| ユーザー | Ghufran Khan (UID 95493) |
|---|
| 送信 | 2026年03月17日 14:23 (19 日 ago) |
|---|
| モデレーション | 2026年04月03日 09:26 (17 days later) |
|---|
| ステータス | 承諾済み |
|---|
| VulDBエントリ | 355071 [Casdoor 2.356.0 OAuth Authorization Request redirect_uri Redirect] |
|---|
| ポイント | 17 |
|---|