Skip to content

Commit

Permalink
Use strict protocol check when redirect (go-gitea#29642)
Browse files Browse the repository at this point in the history
  • Loading branch information
wxiaoguang authored Mar 7, 2024
1 parent 9730d3a commit c72e1a7
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
2 changes: 1 addition & 1 deletion services/context/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,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)
Expand Down
47 changes: 47 additions & 0 deletions services/context/base_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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/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 := 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)
}

req, _ = http.NewRequest("GET", "/", nil)
resp := httptest.NewRecorder()
req.Header.Add("HX-Request", "true")
b, cleanup := NewBaseContext(resp, req)
b.Redirect("/other")
cleanup()
assert.Equal(t, "/other", resp.Header().Get("HX-Redirect"))
assert.Equal(t, http.StatusNoContent, resp.Code)
}

0 comments on commit c72e1a7

Please sign in to comment.