mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-16 15:45:01 +00:00
Backport #38170 by @TheFox0x7 regression from #38039 Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
This commit is contained in:
@@ -65,12 +65,9 @@ var reservedIPNets = sync.OnceValue(func() []*net.IPNet {
|
|||||||
return nets
|
return nets
|
||||||
})
|
})
|
||||||
|
|
||||||
// isPrivateIP reports whether ip falls in a private (net.IP.IsPrivate) or reserved special-purpose
|
// isReservedIP reports whether ip falls in reserved special-purpose
|
||||||
// range (see reservedIPNets) that must not be considered a public/external destination.
|
// range (see reservedIPNets) that must not be considered a public/external destination.
|
||||||
func isPrivateIP(ip net.IP) bool {
|
func isReservedIP(ip net.IP) bool {
|
||||||
if ip.IsPrivate() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, ipNet := range reservedIPNets() {
|
for _, ipNet := range reservedIPNets() {
|
||||||
if ipNet.Contains(ip) {
|
if ipNet.Contains(ip) {
|
||||||
return true
|
return true
|
||||||
@@ -153,18 +150,22 @@ func (hl *HostMatchList) checkPattern(host string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hl *HostMatchList) checkIP(ip net.IP) bool {
|
// matchesIP determines if the given IP matches any of the configured rules
|
||||||
|
func (hl *HostMatchList) matchesIP(ip net.IP) bool {
|
||||||
if slices.Contains(hl.patterns, "*") {
|
if slices.Contains(hl.patterns, "*") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for _, builtin := range hl.builtins {
|
for _, builtin := range hl.builtins {
|
||||||
switch builtin {
|
switch builtin {
|
||||||
case MatchBuiltinExternal:
|
case MatchBuiltinExternal:
|
||||||
if ip.IsGlobalUnicast() && !isPrivateIP(ip) {
|
// External address must be a global unicast, must not be in reserved range and must not be in private range
|
||||||
|
if ip.IsGlobalUnicast() && !isReservedIP(ip) && !ip.IsPrivate() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case MatchBuiltinPrivate:
|
case MatchBuiltinPrivate:
|
||||||
if isPrivateIP(ip) {
|
// Private address must be global unicast, must not be in range we explicitly exclude for security reasons
|
||||||
|
// and must be in private range
|
||||||
|
if ip.IsGlobalUnicast() && !isReservedIP(ip) && ip.IsPrivate() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case MatchBuiltinLoopback:
|
case MatchBuiltinLoopback:
|
||||||
@@ -195,7 +196,7 @@ func (hl *HostMatchList) MatchHostName(host string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if ip := net.ParseIP(hostname); ip != nil {
|
if ip := net.ParseIP(hostname); ip != nil {
|
||||||
return hl.checkIP(ip)
|
return hl.matchesIP(ip)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -206,7 +207,7 @@ func (hl *HostMatchList) MatchIPAddr(ip net.IP) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
host := ip.String() // nil-safe, we will get "<nil>" if ip is nil
|
host := ip.String() // nil-safe, we will get "<nil>" if ip is nil
|
||||||
return hl.checkPattern(host) || hl.checkIP(ip)
|
return hl.checkPattern(host) || hl.matchesIP(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MatchHostOrIP checks if the host or IP matches an allow/deny(block) list
|
// MatchHostOrIP checks if the host or IP matches an allow/deny(block) list
|
||||||
|
|||||||
@@ -202,15 +202,17 @@ func TestReservedRanges(t *testing.T) {
|
|||||||
"198.18.0.1", // benchmarking
|
"198.18.0.1", // benchmarking
|
||||||
"198.51.100.1", // TEST-NET-2
|
"198.51.100.1", // TEST-NET-2
|
||||||
"203.0.113.1", // TEST-NET-3
|
"203.0.113.1", // TEST-NET-3
|
||||||
|
"169.254.169.254", // Cloud metadata
|
||||||
"192.88.99.1", // 6to4 relay anycast
|
"192.88.99.1", // 6to4 relay anycast
|
||||||
"64:ff9b::1", // NAT64
|
"64:ff9b::1", // NAT64
|
||||||
"64:ff9b::a9fe:a9fe", // NAT64 embedding 169.254.169.254
|
"64:ff9b::a9fe:a9fe", // NAT64 embedding 169.254.169.254
|
||||||
"2001::1", // Teredo
|
"2001::1", // Teredo
|
||||||
"2002::1", // 6to4
|
"2002::1", // 6to4
|
||||||
"2001:db8::1", // documentation
|
"2001:db8::1", // documentation
|
||||||
|
"fe80::1", // link local address
|
||||||
} {
|
} {
|
||||||
addr := net.ParseIP(ip)
|
addr := net.ParseIP(ip)
|
||||||
assert.Falsef(t, external.MatchIPAddr(addr), "reserved ip %s must not be external", ip)
|
assert.Falsef(t, external.MatchIPAddr(addr), "reserved ip %s must not be external", ip)
|
||||||
assert.Truef(t, private.MatchIPAddr(addr), "reserved ip %s should match private block-list", ip)
|
assert.Falsef(t, private.MatchIPAddr(addr), "reserved ip %s should match private block-list", ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user