diff --git a/object/application.go b/object/application.go index 1717c912..8f29e8ec 100644 --- a/object/application.go +++ b/object/application.go @@ -723,8 +723,15 @@ func (application *Application) GetId() string { } func (application *Application) IsRedirectUriValid(redirectUri string) bool { - redirectUris := append([]string{"http://localhost:", "https://localhost:", "http://127.0.0.1:", "http://casdoor-app", ".chromiumapp.org"}, application.RedirectUris...) - for _, targetUri := range redirectUris { + isValid, err := util.IsValidOrigin(redirectUri) + if err != nil { + panic(err) + } + if isValid { + return true + } + + for _, targetUri := range application.RedirectUris { targetUriRegex := regexp.MustCompile(targetUri) if targetUriRegex.MatchString(redirectUri) || strings.Contains(redirectUri, targetUri) { return true diff --git a/routers/cors_filter.go b/routers/cors_filter.go index 41dc9c20..36032da2 100644 --- a/routers/cors_filter.go +++ b/routers/cors_filter.go @@ -16,11 +16,11 @@ package routers import ( "net/http" - "strings" "github.com/beego/beego/context" "github.com/casdoor/casdoor/conf" "github.com/casdoor/casdoor/object" + "github.com/casdoor/casdoor/util" ) const ( @@ -52,7 +52,13 @@ func CorsFilter(ctx *context.Context) { origin = "" } - if strings.HasPrefix(origin, "http://localhost") || strings.HasPrefix(origin, "https://localhost") || strings.HasPrefix(origin, "http://127.0.0.1") || strings.HasPrefix(origin, "http://casdoor-app") || strings.Contains(origin, ".chromiumapp.org") { + isValid, err := util.IsValidOrigin(origin) + if err != nil { + ctx.ResponseWriter.WriteHeader(http.StatusForbidden) + responseError(ctx, err.Error()) + return + } + if isValid { setCorsHeaders(ctx, origin) return } diff --git a/util/validation.go b/util/validation.go index e5921980..665a9aea 100644 --- a/util/validation.go +++ b/util/validation.go @@ -17,6 +17,7 @@ package util import ( "fmt" "net/mail" + "net/url" "regexp" "strings" @@ -100,3 +101,21 @@ func GetCountryCode(prefix string, phone string) (string, error) { func FilterField(field string) bool { return ReFieldWhiteList.MatchString(field) } + +func IsValidOrigin(origin string) (bool, error) { + urlObj, err := url.Parse(origin) + if err != nil { + return false, err + } + if urlObj == nil { + return false, nil + } + + originHostOnly := "" + if urlObj.Host != "" { + originHostOnly = fmt.Sprintf("%s://%s", urlObj.Scheme, urlObj.Hostname()) + } + + res := originHostOnly == "http://localhost" || originHostOnly == "https://localhost" || originHostOnly == "http://127.0.0.1" || originHostOnly == "http://casdoor-app" || strings.HasSuffix(originHostOnly, ".chromiumapp.org") + return res, nil +}