TrustedProxies: Add default IPv6 support and refactor (#2967)
This commit is contained in:
@@ -11,7 +11,6 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -28,7 +27,16 @@ var (
|
||||
|
||||
var defaultPlatform string
|
||||
|
||||
var defaultTrustedCIDRs = []*net.IPNet{{IP: net.IP{0x0, 0x0, 0x0, 0x0}, Mask: net.IPMask{0x0, 0x0, 0x0, 0x0}}} // 0.0.0.0/0
|
||||
var defaultTrustedCIDRs = []*net.IPNet{
|
||||
{ // 0.0.0.0/0 (IPv4)
|
||||
IP: net.IP{0x0, 0x0, 0x0, 0x0},
|
||||
Mask: net.IPMask{0x0, 0x0, 0x0, 0x0},
|
||||
},
|
||||
{ // ::/0 (IPv6)
|
||||
IP: net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||
Mask: net.IPMask{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||
},
|
||||
}
|
||||
|
||||
// HandlerFunc defines the handler used by gin middleware as return value.
|
||||
type HandlerFunc func(*Context)
|
||||
@@ -399,9 +407,9 @@ func (engine *Engine) SetTrustedProxies(trustedProxies []string) error {
|
||||
return engine.parseTrustedProxies()
|
||||
}
|
||||
|
||||
// isUnsafeTrustedProxies compares Engine.trustedCIDRs and defaultTrustedCIDRs, it's not safe if equal (returns true)
|
||||
// isUnsafeTrustedProxies checks if Engine.trustedCIDRs contains all IPs, it's not safe if it has (returns true)
|
||||
func (engine *Engine) isUnsafeTrustedProxies() bool {
|
||||
return reflect.DeepEqual(engine.trustedCIDRs, defaultTrustedCIDRs)
|
||||
return engine.isTrustedProxy(net.ParseIP("0.0.0.0")) || engine.isTrustedProxy(net.ParseIP("::"))
|
||||
}
|
||||
|
||||
// parseTrustedProxies parse Engine.trustedProxies to Engine.trustedCIDRs
|
||||
@@ -411,6 +419,41 @@ func (engine *Engine) parseTrustedProxies() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// isTrustedProxy will check whether the IP address is included in the trusted list according to Engine.trustedCIDRs
|
||||
func (engine *Engine) isTrustedProxy(ip net.IP) bool {
|
||||
if engine.trustedCIDRs == nil {
|
||||
return false
|
||||
}
|
||||
for _, cidr := range engine.trustedCIDRs {
|
||||
if cidr.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// validateHeader will parse X-Forwarded-For header and return the trusted client IP address
|
||||
func (engine *Engine) validateHeader(header string) (clientIP string, valid bool) {
|
||||
if header == "" {
|
||||
return "", false
|
||||
}
|
||||
items := strings.Split(header, ",")
|
||||
for i := len(items) - 1; i >= 0; i-- {
|
||||
ipStr := strings.TrimSpace(items[i])
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// X-Forwarded-For is appended by proxy
|
||||
// Check IPs in reverse order and stop when find untrusted proxy
|
||||
if (i == 0) || (!engine.isTrustedProxy(ip)) {
|
||||
return ipStr, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// parseIP parse a string representation of an IP and returns a net.IP with the
|
||||
// minimum byte representation or nil if input is invalid.
|
||||
func parseIP(ip string) net.IP {
|
||||
|
||||
Reference in New Issue
Block a user