mirror of
https://github.com/labstack/echo.git
synced 2025-04-21 12:17:04 +02:00
parent
3598f295f9
commit
a3b0ba24d3
12
ip.go
12
ip.go
@ -228,15 +228,21 @@ func extractIP(req *http.Request) string {
|
|||||||
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
|
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
|
||||||
checker := newIPChecker(options)
|
checker := newIPChecker(options)
|
||||||
return func(req *http.Request) string {
|
return func(req *http.Request) string {
|
||||||
|
directIP := extractIP(req)
|
||||||
realIP := req.Header.Get(HeaderXRealIP)
|
realIP := req.Header.Get(HeaderXRealIP)
|
||||||
if realIP != "" {
|
if realIP == "" {
|
||||||
|
return directIP
|
||||||
|
}
|
||||||
|
|
||||||
|
if checker.trust(net.ParseIP(directIP)) {
|
||||||
realIP = strings.TrimPrefix(realIP, "[")
|
realIP = strings.TrimPrefix(realIP, "[")
|
||||||
realIP = strings.TrimSuffix(realIP, "]")
|
realIP = strings.TrimSuffix(realIP, "]")
|
||||||
if ip := net.ParseIP(realIP); ip != nil && checker.trust(ip) {
|
if rIP := net.ParseIP(realIP); rIP != nil {
|
||||||
return realIP
|
return realIP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extractIP(req)
|
|
||||||
|
return directIP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
69
ip_test.go
69
ip_test.go
@ -4,10 +4,11 @@
|
|||||||
package echo
|
package echo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustParseCIDR(s string) *net.IPNet {
|
func mustParseCIDR(s string) *net.IPNet {
|
||||||
@ -461,7 +462,7 @@ func TestExtractIPDirect(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractIPFromRealIPHeader(t *testing.T) {
|
func TestExtractIPFromRealIPHeader(t *testing.T) {
|
||||||
_, ipForRemoteAddrExternalRange, _ := net.ParseCIDR("203.0.113.199/24")
|
_, ipForRemoteAddrExternalRange, _ := net.ParseCIDR("203.0.113.0/24")
|
||||||
_, ipv6ForRemoteAddrExternalRange, _ := net.ParseCIDR("2001:db8::/64")
|
_, ipv6ForRemoteAddrExternalRange, _ := net.ParseCIDR("2001:db8::/64")
|
||||||
|
|
||||||
var testCases = []struct {
|
var testCases = []struct {
|
||||||
@ -489,26 +490,6 @@ func TestExtractIPFromRealIPHeader(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is from external IP has valid + UNTRUSTED external X-Real-Ip header, extract IP from remote addr",
|
name: "request is from external IP has valid + UNTRUSTED external X-Real-Ip header, extract IP from remote addr",
|
||||||
whenRequest: http.Request{
|
|
||||||
Header: http.Header{
|
|
||||||
HeaderXRealIP: []string{"203.0.113.199"}, // <-- this is untrusted
|
|
||||||
},
|
|
||||||
RemoteAddr: "203.0.113.1:8080",
|
|
||||||
},
|
|
||||||
expectIP: "203.0.113.1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "request is from external IP has valid + UNTRUSTED external X-Real-Ip header, extract IP from remote addr",
|
|
||||||
whenRequest: http.Request{
|
|
||||||
Header: http.Header{
|
|
||||||
HeaderXRealIP: []string{"[2001:db8::113:199]"}, // <-- this is untrusted
|
|
||||||
},
|
|
||||||
RemoteAddr: "[2001:db8::113:1]:8080",
|
|
||||||
},
|
|
||||||
expectIP: "2001:db8::113:1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "request is from external IP has valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
|
||||||
givenTrustOptions: []TrustOption{ // case for "trust direct-facing proxy"
|
givenTrustOptions: []TrustOption{ // case for "trust direct-facing proxy"
|
||||||
TrustIPRange(ipForRemoteAddrExternalRange), // we trust external IP range "203.0.113.199/24"
|
TrustIPRange(ipForRemoteAddrExternalRange), // we trust external IP range "203.0.113.199/24"
|
||||||
},
|
},
|
||||||
@ -516,9 +497,35 @@ func TestExtractIPFromRealIPHeader(t *testing.T) {
|
|||||||
Header: http.Header{
|
Header: http.Header{
|
||||||
HeaderXRealIP: []string{"203.0.113.199"},
|
HeaderXRealIP: []string{"203.0.113.199"},
|
||||||
},
|
},
|
||||||
|
RemoteAddr: "8.8.8.8:8080", // <-- this is untrusted
|
||||||
|
},
|
||||||
|
expectIP: "8.8.8.8",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "request is from external IP has valid + UNTRUSTED external X-Real-Ip header, extract IP from remote addr",
|
||||||
|
givenTrustOptions: []TrustOption{ // case for "trust direct-facing proxy"
|
||||||
|
TrustIPRange(ipv6ForRemoteAddrExternalRange), // we trust external IP range "203.0.113.199/24"
|
||||||
|
},
|
||||||
|
whenRequest: http.Request{
|
||||||
|
Header: http.Header{
|
||||||
|
HeaderXRealIP: []string{"[bc01:1010::9090:1888]"},
|
||||||
|
},
|
||||||
|
RemoteAddr: "[fe64:aa10::1]:8080", // <-- this is untrusted
|
||||||
|
},
|
||||||
|
expectIP: "fe64:aa10::1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "request is from external IP has valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
||||||
|
givenTrustOptions: []TrustOption{ // case for "trust direct-facing proxy"
|
||||||
|
TrustIPRange(ipForRemoteAddrExternalRange), // we trust external IP range "203.0.113.0/24"
|
||||||
|
},
|
||||||
|
whenRequest: http.Request{
|
||||||
|
Header: http.Header{
|
||||||
|
HeaderXRealIP: []string{"8.8.8.8"},
|
||||||
|
},
|
||||||
RemoteAddr: "203.0.113.1:8080",
|
RemoteAddr: "203.0.113.1:8080",
|
||||||
},
|
},
|
||||||
expectIP: "203.0.113.199",
|
expectIP: "8.8.8.8",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is from external IP has valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
name: "request is from external IP has valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
||||||
@ -527,11 +534,11 @@ func TestExtractIPFromRealIPHeader(t *testing.T) {
|
|||||||
},
|
},
|
||||||
whenRequest: http.Request{
|
whenRequest: http.Request{
|
||||||
Header: http.Header{
|
Header: http.Header{
|
||||||
HeaderXRealIP: []string{"[2001:db8::113:199]"},
|
HeaderXRealIP: []string{"[fe64:db8::113:199]"},
|
||||||
},
|
},
|
||||||
RemoteAddr: "[2001:db8::113:1]:8080",
|
RemoteAddr: "[2001:db8::113:1]:8080",
|
||||||
},
|
},
|
||||||
expectIP: "2001:db8::113:199",
|
expectIP: "fe64:db8::113:199",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is from external IP has XFF and valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
name: "request is from external IP has XFF and valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
||||||
@ -540,12 +547,12 @@ func TestExtractIPFromRealIPHeader(t *testing.T) {
|
|||||||
},
|
},
|
||||||
whenRequest: http.Request{
|
whenRequest: http.Request{
|
||||||
Header: http.Header{
|
Header: http.Header{
|
||||||
HeaderXRealIP: []string{"203.0.113.199"},
|
HeaderXRealIP: []string{"8.8.8.8"},
|
||||||
HeaderXForwardedFor: []string{"203.0.113.198, 203.0.113.197"}, // <-- should not affect anything
|
HeaderXForwardedFor: []string{"1.1.1.1 ,8.8.8.8"}, // <-- should not affect anything
|
||||||
},
|
},
|
||||||
RemoteAddr: "203.0.113.1:8080",
|
RemoteAddr: "203.0.113.1:8080",
|
||||||
},
|
},
|
||||||
expectIP: "203.0.113.199",
|
expectIP: "8.8.8.8",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "request is from external IP has XFF and valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
name: "request is from external IP has XFF and valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
|
||||||
@ -554,12 +561,12 @@ func TestExtractIPFromRealIPHeader(t *testing.T) {
|
|||||||
},
|
},
|
||||||
whenRequest: http.Request{
|
whenRequest: http.Request{
|
||||||
Header: http.Header{
|
Header: http.Header{
|
||||||
HeaderXRealIP: []string{"[2001:db8::113:199]"},
|
HeaderXRealIP: []string{"[fe64:db8::113:199]"},
|
||||||
HeaderXForwardedFor: []string{"[2001:db8::113:198], [2001:db8::113:197]"}, // <-- should not affect anything
|
HeaderXForwardedFor: []string{"[feab:cde9::113:198], [fe64:db8::113:199]"}, // <-- should not affect anything
|
||||||
},
|
},
|
||||||
RemoteAddr: "[2001:db8::113:1]:8080",
|
RemoteAddr: "[2001:db8::113:1]:8080",
|
||||||
},
|
},
|
||||||
expectIP: "2001:db8::113:199",
|
expectIP: "fe64:db8::113:199",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user