aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiteabot <teabot@gitea.io>2024-03-07 11:53:33 +0800
committerGitHub <noreply@github.com>2024-03-07 03:53:33 +0000
commit0b5a4e7db483cbbfd8ccb666a11c77e17d59ea08 (patch)
treeea340182c436f8d536287a60e380663728b503ce
parentb6a2b9594af06698b29ea4c649b85e40c7f4b82d (diff)
downloadgitea-0b5a4e7db483cbbfd8ccb666a11c77e17d59ea08.tar.gz
gitea-0b5a4e7db483cbbfd8ccb666a11c77e17d59ea08.zip
Use strict protocol check when redirect (#29642) (#29644)
Backport #29642 by wxiaoguang Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
-rw-r--r--modules/context/base.go2
-rw-r--r--services/context/base_test.go39
2 files changed, 40 insertions, 1 deletions
diff --git a/modules/context/base.go b/modules/context/base.go
index 8df1dde866..87da9ff360 100644
--- a/modules/context/base.go
+++ b/modules/context/base.go
@@ -255,7 +255,7 @@ func (b *Base) Redirect(location string, status ...int) {
code = status[0]
}
- if strings.Contains(location, "://") || strings.HasPrefix(location, "//") {
+ if strings.HasPrefix(location, "http://") || strings.HasPrefix(location, "https://") || strings.HasPrefix(location, "//") {
// Some browsers (Safari) have buggy behavior for Cookie + Cache + External Redirection, eg: /my-path => https://other/path
// 1. the first request to "/my-path" contains cookie
// 2. some time later, the request to "/my-path" doesn't contain cookie (caused by Prevent web tracking)
diff --git a/services/context/base_test.go b/services/context/base_test.go
new file mode 100644
index 0000000000..96ccfa73e3
--- /dev/null
+++ b/services/context/base_test.go
@@ -0,0 +1,39 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package context
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/setting"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRedirect(t *testing.T) {
+ req, _ := http.NewRequest("GET", "/", nil)
+
+ cases := []struct {
+ url string
+ keep bool
+ }{
+ {"http://test", false},
+ {"https://test", false},
+ {"//test", false},
+ {"/://test", true},
+ {"/test", true},
+ }
+ for _, c := range cases {
+ resp := httptest.NewRecorder()
+ b, cleanup := context.NewBaseContext(resp, req)
+ resp.Header().Add("Set-Cookie", (&http.Cookie{Name: setting.SessionConfig.CookieName, Value: "dummy"}).String())
+ b.Redirect(c.url)
+ cleanup()
+ has := resp.Header().Get("Set-Cookie") == "i_like_gitea=dummy"
+ assert.Equal(t, c.keep, has, "url = %q", c.url)
+ }
+}