🩹 Fix: handle multiple X-Forwarded header (#2154)

* fix: handle multiple XForwarded

* fix: use strings.Index instead of strings.Split

Co-authored-by: Supakorn Wongsawang <supakorn.wongsawang@agoda.com>
pull/2162/head
Supakorn Wongsawang 2022-10-18 16:23:35 +07:00 committed by GitHub
parent 2b7a632a19
commit 709b132dca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 2 deletions

19
ctx.go
View File

@ -661,6 +661,10 @@ func (c *Ctx) GetRespHeaders() map[string]string {
func (c *Ctx) Hostname() string {
if c.IsProxyTrusted() {
if host := c.Get(HeaderXForwardedHost); len(host) > 0 {
commaPos := strings.Index(host, ",")
if commaPos != -1 {
return host[:commaPos]
}
return host
}
}
@ -1014,10 +1018,21 @@ func (c *Ctx) Protocol() string {
if len(key) < 12 {
return // X-Forwarded-
} else if bytes.HasPrefix(key, []byte("X-Forwarded-")) {
v := c.app.getString(val)
if bytes.Equal(key, []byte(HeaderXForwardedProto)) {
scheme = c.app.getString(val)
commaPos := strings.Index(v, ",")
if commaPos != -1 {
scheme = v[:commaPos]
} else {
scheme = v
}
} else if bytes.Equal(key, []byte(HeaderXForwardedProtocol)) {
scheme = c.app.getString(val)
commaPos := strings.Index(v, ",")
if commaPos != -1 {
scheme = v[:commaPos]
} else {
scheme = v
}
} else if bytes.Equal(key, []byte(HeaderXForwardedSsl)) && bytes.Equal(val, []byte("on")) {
scheme = "https"
}

View File

@ -1071,6 +1071,19 @@ func Test_Ctx_Hostname_TrustedProxy(t *testing.T) {
}
}
// go test -run Test_Ctx_Hostname_Trusted_Multiple
func Test_Ctx_Hostname_TrustedProxy_Multiple(t *testing.T) {
t.Parallel()
{
app := New(Config{EnableTrustedProxyCheck: true, TrustedProxies: []string{"0.0.0.0", "0.8.0.1"}})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
c.Request().Header.Set(HeaderXForwardedHost, "google1.com, google2.com")
utils.AssertEqual(t, "google1.com", c.Hostname())
app.ReleaseCtx(c)
}
}
// go test -run Test_Ctx_Hostname_UntrustedProxyRange
func Test_Ctx_Hostname_TrustedProxyRange(t *testing.T) {
t.Parallel()
@ -1824,6 +1837,14 @@ func Test_Ctx_Protocol(t *testing.T) {
utils.AssertEqual(t, "https", c.Protocol())
c.Request().Header.Reset()
c.Request().Header.Set(HeaderXForwardedProto, "https, http")
utils.AssertEqual(t, "https", c.Protocol())
c.Request().Header.Reset()
c.Request().Header.Set(HeaderXForwardedProtocol, "https, http")
utils.AssertEqual(t, "https", c.Protocol())
c.Request().Header.Reset()
c.Request().Header.Set(HeaderXForwardedSsl, "on")
utils.AssertEqual(t, "https", c.Protocol())
c.Request().Header.Reset()