Fix duplicate entry for X-Forwarded-For header (#32039)

* Fix duplicate entry for `X-Forwarded-For` header

PR #27761 replaced `oxy.Forwarder` with `httputil.ReverseProxy`.
The new forwarder based on `httputil.ReverseProxy` is appending the
`X-Forwarder-For` header values instead of replacing them.
This PR fixes that behavior and forces the XFF header to be a single
value.

Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>

* Update lib/httplib/reverseproxy/rewriter_test.go

Co-authored-by: Reed Loden <reed@goteleport.com>

---------

Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>
Co-authored-by: Reed Loden <reed@goteleport.com>
This commit is contained in:
Tiago Silva 2023-09-18 20:21:41 +01:00 committed by GitHub
parent fbbe702384
commit f476eddbb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 7 deletions

View file

@ -54,8 +54,8 @@ func (rw *HeaderRewriter) Rewrite(req *http.Request) {
// Set X-Real-IP header if it is not set to the IP address of the client making the request.
maybeSetXRealIP(req)
// Set X-Forwarded-Proto header if it is not set to the scheme of the request.
maybeSetForwardedProto(req)
// Set X-Forwarded-* headers if it is not set to the scheme of the request.
maybeSetForwarded(req)
if xfPort := req.Header.Get(XForwardedPort); xfPort == "" {
req.Header.Set(XForwardedPort, forwardedPort(req))
@ -104,9 +104,13 @@ func maybeSetXRealIP(req *http.Request) {
}
}
// maybeSetForwardedProto sets X-Forwarded-Proto header if it is not set to the
// maybeSetForwarded sets X-Forwarded-* headers if it is not set to the
// scheme of the request.
func maybeSetForwardedProto(req *http.Request) {
func maybeSetForwarded(req *http.Request) {
// We need to delete the value because httputil.ReverseProxy
// appends to the existing value.
req.Header.Del(XForwardedFor)
if req.Header.Get(XForwardedProto) != "" {
return
}

View file

@ -90,7 +90,9 @@ func TestRewriter(t *testing.T) {
}{
{
desc: "set x-real-ip",
reqHeaders: http.Header{},
reqHeaders: http.Header{
XForwardedFor: []string{"1.2.3.4"},
},
tlsReq: true,
hostReq: "teleport.dev:3543",
remoteAddr: "1.2.3.4:1234",
@ -106,6 +108,7 @@ func TestRewriter(t *testing.T) {
desc: "trust x-real-ip",
reqHeaders: http.Header{
XRealIP: []string{"5.6.7.8"},
XForwardedFor: []string{"1.2.3.4"},
},
tlsReq: false,
hostReq: "teleport.dev:3543",