Only use Host header from reverse proxy (#32060)

X-Forwarded-Host has many problems: non-standard, not well-defined
(X-Forwarded-Port or not), conflicts with Host header, it already caused
problems like #31907. So do not use X-Forwarded-Host, just use Host
header directly.

Official document also only uses `Host` header and never mentioned
others.
pull/31689/head^2
wxiaoguang 2 months ago committed by GitHub
parent 55d5a74bb3
commit 3b10fd9b34
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      .github/workflows/pull-db-tests.yml
  2. 13
      modules/httplib/url.go
  3. 5
      modules/httplib/url_test.go

@ -201,7 +201,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
mssql: mssql:
image: mcr.microsoft.com/mssql/server:2017-latest # some images before 2024-04 can't run on new kernels
image: mcr.microsoft.com/mssql/server:2019-latest
env: env:
ACCEPT_EULA: Y ACCEPT_EULA: Y
MSSQL_PID: Standard MSSQL_PID: Standard

@ -52,11 +52,6 @@ func getRequestScheme(req *http.Request) string {
return "" return ""
} }
func getForwardedHost(req *http.Request) string {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
return req.Header.Get("X-Forwarded-Host")
}
// GuessCurrentAppURL tries to guess the current full app URL (with sub-path) by http headers. It always has a '/' suffix, exactly the same as setting.AppURL // GuessCurrentAppURL tries to guess the current full app URL (with sub-path) by http headers. It always has a '/' suffix, exactly the same as setting.AppURL
func GuessCurrentAppURL(ctx context.Context) string { func GuessCurrentAppURL(ctx context.Context) string {
return GuessCurrentHostURL(ctx) + setting.AppSubURL + "/" return GuessCurrentHostURL(ctx) + setting.AppSubURL + "/"
@ -81,11 +76,9 @@ func GuessCurrentHostURL(ctx context.Context) string {
if reqScheme == "" { if reqScheme == "" {
return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/") return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/")
} }
reqHost := getForwardedHost(req) // X-Forwarded-Host has many problems: non-standard, not well-defined (X-Forwarded-Port or not), conflicts with Host header.
if reqHost == "" { // So do not use X-Forwarded-Host, just use Host header directly.
reqHost = req.Host return reqScheme + "://" + req.Host
}
return reqScheme + "://" + reqHost
} }
// MakeAbsoluteURL tries to make a link to an absolute URL: // MakeAbsoluteURL tries to make a link to an absolute URL:

@ -70,7 +70,7 @@ func TestMakeAbsoluteURL(t *testing.T) {
"X-Forwarded-Proto": {"https"}, "X-Forwarded-Proto": {"https"},
}, },
}) })
assert.Equal(t, "https://forwarded-host/foo", MakeAbsoluteURL(ctx, "/foo")) assert.Equal(t, "https://user-host/foo", MakeAbsoluteURL(ctx, "/foo"))
} }
func TestIsCurrentGiteaSiteURL(t *testing.T) { func TestIsCurrentGiteaSiteURL(t *testing.T) {
@ -119,5 +119,6 @@ func TestIsCurrentGiteaSiteURL(t *testing.T) {
}, },
}) })
assert.True(t, IsCurrentGiteaSiteURL(ctx, "http://localhost:3000")) assert.True(t, IsCurrentGiteaSiteURL(ctx, "http://localhost:3000"))
assert.True(t, IsCurrentGiteaSiteURL(ctx, "https://forwarded-host")) assert.True(t, IsCurrentGiteaSiteURL(ctx, "https://user-host"))
assert.False(t, IsCurrentGiteaSiteURL(ctx, "https://forwarded-host"))
} }

Loading…
Cancel
Save