Skip to content

Commit 234d88f

Browse files
wxiaoguangGiteaBot
authored andcommitted
Use strict protocol check when redirect (go-gitea#29642)
1 parent b6a2b95 commit 234d88f

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

modules/context/base.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ func (b *Base) Redirect(location string, status ...int) {
255255
code = status[0]
256256
}
257257

258-
if strings.Contains(location, "://") || strings.HasPrefix(location, "//") {
258+
if strings.HasPrefix(location, "http://") || strings.HasPrefix(location, "https://") || strings.HasPrefix(location, "//") {
259259
// Some browsers (Safari) have buggy behavior for Cookie + Cache + External Redirection, eg: /my-path => https://other/path
260260
// 1. the first request to "/my-path" contains cookie
261261
// 2. some time later, the request to "/my-path" doesn't contain cookie (caused by Prevent web tracking)

services/context/base_test.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package context
5+
6+
import (
7+
"net/http"
8+
"net/http/httptest"
9+
"testing"
10+
11+
"code.gitea.io/gitea/modules/setting"
12+
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestRedirect(t *testing.T) {
17+
req, _ := http.NewRequest("GET", "/", nil)
18+
19+
cases := []struct {
20+
url string
21+
keep bool
22+
}{
23+
{"http://test", false},
24+
{"https://test", false},
25+
{"//test", false},
26+
{"/://test", true},
27+
{"/test", true},
28+
}
29+
for _, c := range cases {
30+
resp := httptest.NewRecorder()
31+
b, cleanup := NewBaseContext(resp, req)
32+
resp.Header().Add("Set-Cookie", (&http.Cookie{Name: setting.SessionConfig.CookieName, Value: "dummy"}).String())
33+
b.Redirect(c.url)
34+
cleanup()
35+
has := resp.Header().Get("Set-Cookie") == "i_like_gitea=dummy"
36+
assert.Equal(t, c.keep, has, "url = %q", c.url)
37+
}
38+
39+
req, _ = http.NewRequest("GET", "/", nil)
40+
resp := httptest.NewRecorder()
41+
req.Header.Add("HX-Request", "true")
42+
b, cleanup := NewBaseContext(resp, req)
43+
b.Redirect("/other")
44+
cleanup()
45+
assert.Equal(t, "/other", resp.Header().Get("HX-Redirect"))
46+
assert.Equal(t, http.StatusNoContent, resp.Code)
47+
}

0 commit comments

Comments
 (0)