]> source.dussan.org Git - gitea.git/commitdiff
Use strict protocol check when redirect (#29642) (#29644)
authorGiteabot <teabot@gitea.io>
Thu, 7 Mar 2024 03:53:33 +0000 (11:53 +0800)
committerGitHub <noreply@github.com>
Thu, 7 Mar 2024 03:53:33 +0000 (03:53 +0000)
Backport #29642 by wxiaoguang

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
modules/context/base.go
services/context/base_test.go [new file with mode: 0644]

index 8df1dde866d5bb0fd895f5826666eabb4d0abda6..87da9ff3605ad87360219764a0a91ce69a960591 100644 (file)
@@ -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 (file)
index 0000000..96ccfa7
--- /dev/null
@@ -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)
+       }
+}