mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-10-22 17:24:26 +00:00
xff[0]
This commit is contained in:
@@ -11,38 +11,24 @@ import (
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
)
|
||||
|
||||
func parseXForwardedFor(xff string) []net.Address {
|
||||
list := strings.Split(xff, ",")
|
||||
addrs := make([]net.Address, 0, len(list))
|
||||
for _, proxy := range list {
|
||||
addrs = append(addrs, net.ParseAddress(proxy))
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
// ParseTrustedXForwardedFor parses forwarding headers only when a configured trusted header is present.
|
||||
func ParseTrustedXForwardedFor(header http.Header, trusted []string, clientAddr gonet.Addr) []net.Address {
|
||||
key := "X-Real-IP"
|
||||
value := header.Get(key)
|
||||
if value == "" {
|
||||
key = "X-Forwarded-For"
|
||||
value = header.Get(key)
|
||||
}
|
||||
func ParseTrustedXForwardedFor(header http.Header, trusted []string, remoteAddr gonet.Addr) net.Address {
|
||||
value := header.Get("X-Forwarded-For")
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
for _, t := range trusted {
|
||||
if len(header.Values(t)) > 0 {
|
||||
if key == "X-Real-IP" {
|
||||
return []net.Address{net.ParseAddress(value)}
|
||||
if idx := strings.IndexByte(value, ','); idx >= 0 {
|
||||
value = value[:idx]
|
||||
}
|
||||
return parseXForwardedFor(value)
|
||||
return net.ParseAddress(value)
|
||||
}
|
||||
}
|
||||
if len(trusted) == 0 {
|
||||
errors.LogWarning(context.Background(), `received "`, key, `" from `, clientAddr, ` but "sockopt.trustedXForwardedFor" is not configured; ignoring it and using the real remote address`)
|
||||
errors.LogWarning(context.Background(), `received "X-Forwarded-For" from `, remoteAddr, ` but "sockopt.trustedXForwardedFor" is not configured; ignoring it and using the real remote address`)
|
||||
} else {
|
||||
errors.LogError(context.Background(), `ignored potentially forged "`, key, `" from `, clientAddr, `: `, value)
|
||||
errors.LogError(context.Background(), `ignored potentially forged "X-Forwarded-For" from `, remoteAddr, `: `, value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,21 +7,20 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
. "github.com/xtls/xray-core/common/protocol/http"
|
||||
)
|
||||
|
||||
func TestParseTrustedXForwardedFor(t *testing.T) {
|
||||
clientAddr := &gonet.TCPAddr{IP: gonet.ParseIP("127.0.0.1"), Port: 12345}
|
||||
remoteAddr := &gonet.TCPAddr{IP: gonet.ParseIP("127.0.0.1"), Port: 12345}
|
||||
|
||||
t.Run("ignore X-Forwarded-For without trusted header", func(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("X-Forwarded-For", "129.78.138.66, 129.78.64.103")
|
||||
|
||||
if addrs := ParseTrustedXForwardedFor(header, nil, clientAddr); addrs != nil {
|
||||
t.Fatalf("unexpected trusted X-Forwarded-For: %v", addrs)
|
||||
if addr := ParseTrustedXForwardedFor(header, nil, remoteAddr); addr != nil {
|
||||
t.Fatalf("unexpected trusted X-Forwarded-For: %v", addr)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -30,32 +29,9 @@ func TestParseTrustedXForwardedFor(t *testing.T) {
|
||||
header.Add("X-Forwarded-For", "129.78.138.66, 129.78.64.103")
|
||||
header.Add("X-Trusted-CDN", "")
|
||||
|
||||
addrs := ParseTrustedXForwardedFor(header, []string{"X-Trusted-CDN"}, clientAddr)
|
||||
if r := cmp.Diff(addrs, []net.Address{net.ParseAddress("129.78.138.66"), net.ParseAddress("129.78.64.103")}); r != "" {
|
||||
t.Error(r)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("prefer X-Real-IP over X-Forwarded-For", func(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("X-Real-IP", "10.0.0.1")
|
||||
header.Add("X-Forwarded-For", "129.78.138.66, 129.78.64.103")
|
||||
header.Add("X-Trusted-CDN", "")
|
||||
|
||||
addrs := ParseTrustedXForwardedFor(header, []string{"X-Trusted-CDN"}, clientAddr)
|
||||
if r := cmp.Diff(addrs, []net.Address{net.ParseAddress("10.0.0.1")}); r != "" {
|
||||
t.Error(r)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("do not parse X-Real-IP as a list", func(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("X-Real-IP", "8.8.8.8, 9.9.9.9")
|
||||
header.Add("X-Trusted-CDN", "")
|
||||
|
||||
addrs := ParseTrustedXForwardedFor(header, []string{"X-Trusted-CDN"}, clientAddr)
|
||||
if r := cmp.Diff(addrs, []net.Address{net.ParseAddress("8.8.8.8, 9.9.9.9")}); r != "" {
|
||||
t.Error(r)
|
||||
addr := ParseTrustedXForwardedFor(header, []string{"X-Trusted-CDN"}, remoteAddr)
|
||||
if addr != net.ParseAddress("129.78.138.66") {
|
||||
t.Fatalf("unexpected trusted X-Forwarded-For: %v", addr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user