From 5b832c1724717b9d82fa4e148ccaa2bbfa8669aa Mon Sep 17 00:00:00 2001 From: "stonezdj(Daojun Zhang)" Date: Sat, 24 Feb 2024 09:34:30 +0800 Subject: [PATCH] Limit url to local path (#20025) --- src/common/utils/utils.go | 5 +++++ src/common/utils/utils_test.go | 22 ++++++++++++++++++++++ src/core/controllers/oidc.go | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/common/utils/utils.go b/src/common/utils/utils.go index ab07c3ed3..07597492e 100644 --- a/src/common/utils/utils.go +++ b/src/common/utils/utils.go @@ -332,3 +332,8 @@ func MostMatchSorter(a, b string, matchWord string) bool { } return len(a) < len(b) } + +// IsLocalPath checks if path is local +func IsLocalPath(path string) bool { + return strings.HasPrefix(path, "/") && !strings.HasPrefix(path, "//") +} diff --git a/src/common/utils/utils_test.go b/src/common/utils/utils_test.go index 73d9fb28b..8849e1f0c 100644 --- a/src/common/utils/utils_test.go +++ b/src/common/utils/utils_test.go @@ -486,3 +486,25 @@ func TestValidateCronString(t *testing.T) { } } } + +func TestIsLocalPath(t *testing.T) { + type args struct { + path string + } + tests := []struct { + name string + args args + want bool + }{ + {"normal test", args{"/harbor/project"}, true}, + {"failed", args{"www.myexample.com"}, false}, + {"other_site1", args{"//www.myexample.com"}, false}, + {"other_site2", args{"https://www.myexample.com"}, false}, + {"other_site", args{"http://www.myexample.com"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, IsLocalPath(tt.args.path), "IsLocalPath(%v)", tt.args.path) + }) + } +} diff --git a/src/core/controllers/oidc.go b/src/core/controllers/oidc.go index c929676c2..295acb2cf 100644 --- a/src/core/controllers/oidc.go +++ b/src/core/controllers/oidc.go @@ -64,7 +64,7 @@ func (oc *OIDCController) RedirectLogin() { return } redirectURL := oc.Ctx.Request.URL.Query().Get("redirect_url") - if strings.HasPrefix(redirectURL, "//") { + if !utils.IsLocalPath(redirectURL) { log.Errorf("invalid redirect url: %v", redirectURL) oc.SendBadRequestError(fmt.Errorf("cannot redirect to other site")) return