diff options
author | Giteabot <teabot@gitea.io> | 2024-03-07 11:53:33 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-07 03:53:33 +0000 |
commit | 0b5a4e7db483cbbfd8ccb666a11c77e17d59ea08 (patch) | |
tree | ea340182c436f8d536287a60e380663728b503ce | |
parent | b6a2b9594af06698b29ea4c649b85e40c7f4b82d (diff) | |
download | gitea-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.go | 2 | ||||
-rw-r--r-- | services/context/base_test.go | 39 |
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) + } +} |