Allow disabling of all X-Forwarded-For header processing (#20977)

This commit is contained in:
Mark Theunissen 2025-02-26 20:25:49 +01:00 committed by GitHub
parent f129fd48f2
commit 7cc0c69228
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 22 deletions

View File

@ -26,6 +26,9 @@ import (
"net/http" "net/http"
"regexp" "regexp"
"strings" "strings"
"github.com/minio/minio/internal/config"
"github.com/minio/pkg/v3/env"
) )
var ( var (
@ -51,6 +54,9 @@ var (
protoRegex = regexp.MustCompile(`(?i)^(;|,| )+(?:proto=)(https|http)`) protoRegex = regexp.MustCompile(`(?i)^(;|,| )+(?:proto=)(https|http)`)
) )
// Used to disable all processing of the X-Forwarded-For header in source IP discovery.
var enableXFFHeader = env.Get("_MINIO_API_XFF_HEADER", config.EnableOn) == config.EnableOn
// GetSourceScheme retrieves the scheme from the X-Forwarded-Proto and RFC7239 // GetSourceScheme retrieves the scheme from the X-Forwarded-Proto and RFC7239
// Forwarded headers (in that order). // Forwarded headers (in that order).
func GetSourceScheme(r *http.Request) string { func GetSourceScheme(r *http.Request) string {
@ -84,6 +90,7 @@ func GetSourceScheme(r *http.Request) string {
func GetSourceIPFromHeaders(r *http.Request) string { func GetSourceIPFromHeaders(r *http.Request) string {
var addr string var addr string
if enableXFFHeader {
if fwd := r.Header.Get(xForwardedFor); fwd != "" { if fwd := r.Header.Get(xForwardedFor); fwd != "" {
// Only grab the first (client) address. Note that '192.168.0.1, // Only grab the first (client) address. Note that '192.168.0.1,
// 10.1.1.1' is a valid key for X-Forwarded-For where addresses after // 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
@ -93,7 +100,11 @@ func GetSourceIPFromHeaders(r *http.Request) string {
s = len(fwd) s = len(fwd)
} }
addr = fwd[:s] addr = fwd[:s]
} else if fwd := r.Header.Get(xRealIP); fwd != "" { }
}
if addr == "" {
if fwd := r.Header.Get(xRealIP); fwd != "" {
// X-Real-IP should only contain one IP address (the client making the // X-Real-IP should only contain one IP address (the client making the
// request). // request).
addr = fwd addr = fwd
@ -109,6 +120,7 @@ func GetSourceIPFromHeaders(r *http.Request) string {
addr = strings.Trim(match[1], `"`) addr = strings.Trim(match[1], `"`)
} }
} }
}
return addr return addr
} }

View File

@ -84,3 +84,27 @@ func TestGetSourceIP(t *testing.T) {
} }
} }
} }
func TestXFFDisabled(t *testing.T) {
req := &http.Request{
Header: http.Header{
xForwardedFor: []string{"8.8.8.8"},
xRealIP: []string{"1.1.1.1"},
},
}
// When X-Forwarded-For and X-Real-IP headers are both present, X-Forwarded-For takes precedence.
res := GetSourceIP(req)
if res != "8.8.8.8" {
t.Errorf("wrong header, xff takes precedence: got %s, want: 8.8.8.8", res)
}
// When explicitly disabled, the XFF header is ignored and X-Real-IP is used.
enableXFFHeader = false
defer func() {
enableXFFHeader = true
}()
res = GetSourceIP(req)
if res != "1.1.1.1" {
t.Errorf("wrong header, xff is disabled: got %s, want: 1.1.1.1", res)
}
}