mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 00:47:33 +00:00
fix: correctly check denied domains and ips for actions (#8810)
# Which Problems Are Solved System administrators can block hosts and IPs for HTTP calls in actions. Using DNS, blocked IPs could be bypassed. # How the Problems Are Solved - Hosts are resolved (DNS lookup) to check whether their corresponding IP is blocked. # Additional Changes - Added complete lookup ip address range and "unspecified" address to the default `DenyList`
This commit is contained in:
@@ -6,8 +6,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
func SetHTTPConfig(config *HTTPConfig) {
|
||||
@@ -48,7 +46,7 @@ func HTTPConfigDecodeHook(from, to reflect.Value) (interface{}, error) {
|
||||
|
||||
for _, unsplit := range config.DenyList {
|
||||
for _, split := range strings.Split(unsplit, ",") {
|
||||
parsed, parseErr := parseDenyListEntry(split)
|
||||
parsed, parseErr := NewHostChecker(split)
|
||||
if parseErr != nil {
|
||||
return nil, parseErr
|
||||
}
|
||||
@@ -61,46 +59,36 @@ func HTTPConfigDecodeHook(from, to reflect.Value) (interface{}, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func parseDenyListEntry(entry string) (AddressChecker, error) {
|
||||
if checker, err := NewIPChecker(entry); err == nil {
|
||||
return checker, nil
|
||||
}
|
||||
return &DomainChecker{Domain: entry}, nil
|
||||
}
|
||||
|
||||
func NewIPChecker(i string) (AddressChecker, error) {
|
||||
_, network, err := net.ParseCIDR(i)
|
||||
func NewHostChecker(entry string) (AddressChecker, error) {
|
||||
_, network, err := net.ParseCIDR(entry)
|
||||
if err == nil {
|
||||
return &IPChecker{Net: network}, nil
|
||||
return &HostChecker{Net: network}, nil
|
||||
}
|
||||
if ip := net.ParseIP(i); ip != nil {
|
||||
return &IPChecker{IP: ip}, nil
|
||||
if ip := net.ParseIP(entry); ip != nil {
|
||||
return &HostChecker{IP: ip}, nil
|
||||
}
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "ACTIO-ddJ7h", "invalid ip")
|
||||
return &HostChecker{Domain: entry}, nil
|
||||
}
|
||||
|
||||
type IPChecker struct {
|
||||
Net *net.IPNet
|
||||
IP net.IP
|
||||
}
|
||||
|
||||
func (c *IPChecker) Matches(address string) bool {
|
||||
ip := net.ParseIP(address)
|
||||
if ip == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if c.IP != nil {
|
||||
return c.IP.Equal(ip)
|
||||
}
|
||||
return c.Net.Contains(ip)
|
||||
}
|
||||
|
||||
type DomainChecker struct {
|
||||
type HostChecker struct {
|
||||
Net *net.IPNet
|
||||
IP net.IP
|
||||
Domain string
|
||||
}
|
||||
|
||||
func (c *DomainChecker) Matches(domain string) bool {
|
||||
//TODO: allow wild cards
|
||||
return c.Domain == domain
|
||||
func (c *HostChecker) Matches(ips []net.IP, address string) bool {
|
||||
// if the address matches the domain, no additional checks as needed
|
||||
if c.Domain == address {
|
||||
return true
|
||||
}
|
||||
// otherwise we need to check on ips (incl. the resolved ips of the host)
|
||||
for _, ip := range ips {
|
||||
if c.Net != nil && c.Net.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
if c.IP != nil && c.IP.Equal(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
Reference in New Issue
Block a user