Skip to content

Commit a3b0ba2

Browse files
authored
Fix Real IP logic (#2550)
* Fix realIP logic
1 parent 3598f29 commit a3b0ba2

File tree

2 files changed

+35
-22
lines changed

2 files changed

+35
-22
lines changed

ip.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,21 @@ func extractIP(req *http.Request) string {
228228
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
229229
checker := newIPChecker(options)
230230
return func(req *http.Request) string {
231+
directIP := extractIP(req)
231232
realIP := req.Header.Get(HeaderXRealIP)
232-
if realIP != "" {
233+
if realIP == "" {
234+
return directIP
235+
}
236+
237+
if checker.trust(net.ParseIP(directIP)) {
233238
realIP = strings.TrimPrefix(realIP, "[")
234239
realIP = strings.TrimSuffix(realIP, "]")
235-
if ip := net.ParseIP(realIP); ip != nil && checker.trust(ip) {
240+
if rIP := net.ParseIP(realIP); rIP != nil {
236241
return realIP
237242
}
238243
}
239-
return extractIP(req)
244+
245+
return directIP
240246
}
241247
}
242248

ip_test.go

+26-19
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
package echo
55

66
import (
7-
"github.com/stretchr/testify/assert"
87
"net"
98
"net/http"
109
"testing"
10+
11+
"github.com/stretchr/testify/assert"
1112
)
1213

1314
func mustParseCIDR(s string) *net.IPNet {
@@ -461,7 +462,7 @@ func TestExtractIPDirect(t *testing.T) {
461462
}
462463

463464
func TestExtractIPFromRealIPHeader(t *testing.T) {
464-
_, ipForRemoteAddrExternalRange, _ := net.ParseCIDR("203.0.113.199/24")
465+
_, ipForRemoteAddrExternalRange, _ := net.ParseCIDR("203.0.113.0/24")
465466
_, ipv6ForRemoteAddrExternalRange, _ := net.ParseCIDR("2001:db8::/64")
466467

467468
var testCases = []struct {
@@ -489,36 +490,42 @@ func TestExtractIPFromRealIPHeader(t *testing.T) {
489490
},
490491
{
491492
name: "request is from external IP has valid + UNTRUSTED external X-Real-Ip header, extract IP from remote addr",
493+
givenTrustOptions: []TrustOption{ // case for "trust direct-facing proxy"
494+
TrustIPRange(ipForRemoteAddrExternalRange), // we trust external IP range "203.0.113.199/24"
495+
},
492496
whenRequest: http.Request{
493497
Header: http.Header{
494-
HeaderXRealIP: []string{"203.0.113.199"}, // <-- this is untrusted
498+
HeaderXRealIP: []string{"203.0.113.199"},
495499
},
496-
RemoteAddr: "203.0.113.1:8080",
500+
RemoteAddr: "8.8.8.8:8080", // <-- this is untrusted
497501
},
498-
expectIP: "203.0.113.1",
502+
expectIP: "8.8.8.8",
499503
},
500504
{
501505
name: "request is from external IP has valid + UNTRUSTED external X-Real-Ip header, extract IP from remote addr",
506+
givenTrustOptions: []TrustOption{ // case for "trust direct-facing proxy"
507+
TrustIPRange(ipv6ForRemoteAddrExternalRange), // we trust external IP range "203.0.113.199/24"
508+
},
502509
whenRequest: http.Request{
503510
Header: http.Header{
504-
HeaderXRealIP: []string{"[2001:db8::113:199]"}, // <-- this is untrusted
511+
HeaderXRealIP: []string{"[bc01:1010::9090:1888]"},
505512
},
506-
RemoteAddr: "[2001:db8::113:1]:8080",
513+
RemoteAddr: "[fe64:aa10::1]:8080", // <-- this is untrusted
507514
},
508-
expectIP: "2001:db8::113:1",
515+
expectIP: "fe64:aa10::1",
509516
},
510517
{
511518
name: "request is from external IP has valid + TRUSTED X-Real-Ip header, extract IP from X-Real-Ip header",
512519
givenTrustOptions: []TrustOption{ // case for "trust direct-facing proxy"
513-
TrustIPRange(ipForRemoteAddrExternalRange), // we trust external IP range "203.0.113.199/24"
520+
TrustIPRange(ipForRemoteAddrExternalRange), // we trust external IP range "203.0.113.0/24"
514521
},
515522
whenRequest: http.Request{
516523
Header: http.Header{
517-
HeaderXRealIP: []string{"203.0.113.199"},
524+
HeaderXRealIP: []string{"8.8.8.8"},
518525
},
519526
RemoteAddr: "203.0.113.1:8080",
520527
},
521-
expectIP: "203.0.113.199",
528+
expectIP: "8.8.8.8",
522529
},
523530
{
524531
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) {
527534
},
528535
whenRequest: http.Request{
529536
Header: http.Header{
530-
HeaderXRealIP: []string{"[2001:db8::113:199]"},
537+
HeaderXRealIP: []string{"[fe64:db8::113:199]"},
531538
},
532539
RemoteAddr: "[2001:db8::113:1]:8080",
533540
},
534-
expectIP: "2001:db8::113:199",
541+
expectIP: "fe64:db8::113:199",
535542
},
536543
{
537544
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) {
540547
},
541548
whenRequest: http.Request{
542549
Header: http.Header{
543-
HeaderXRealIP: []string{"203.0.113.199"},
544-
HeaderXForwardedFor: []string{"203.0.113.198, 203.0.113.197"}, // <-- should not affect anything
550+
HeaderXRealIP: []string{"8.8.8.8"},
551+
HeaderXForwardedFor: []string{"1.1.1.1 ,8.8.8.8"}, // <-- should not affect anything
545552
},
546553
RemoteAddr: "203.0.113.1:8080",
547554
},
548-
expectIP: "203.0.113.199",
555+
expectIP: "8.8.8.8",
549556
},
550557
{
551558
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) {
554561
},
555562
whenRequest: http.Request{
556563
Header: http.Header{
557-
HeaderXRealIP: []string{"[2001:db8::113:199]"},
558-
HeaderXForwardedFor: []string{"[2001:db8::113:198], [2001:db8::113:197]"}, // <-- should not affect anything
564+
HeaderXRealIP: []string{"[fe64:db8::113:199]"},
565+
HeaderXForwardedFor: []string{"[feab:cde9::113:198], [fe64:db8::113:199]"}, // <-- should not affect anything
559566
},
560567
RemoteAddr: "[2001:db8::113:1]:8080",
561568
},
562-
expectIP: "2001:db8::113:199",
569+
expectIP: "fe64:db8::113:199",
563570
},
564571
}
565572

0 commit comments

Comments
 (0)