Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions internal/fields/_static/allowed_geo_ips.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
1.128.3.4
175.16.199.1
216.160.83.57
216.160.83.61
81.2.69.143
81.2.69.144
81.2.69.145
81.2.69.193
89.160.20.112
89.160.20.156
67.43.156.12
67.43.156.13
67.43.156.14
67.43.156.15
2a02:cf40:add:4002:91f2:a9b2:e09a:6fc6
1.128.0.0/11
175.16.199.0/24
216.160.83.56/29
81.2.69.142/31
81.2.69.192/28
89.160.20.112/28
89.160.20.128/25
67.43.156.0/24
2a02:cf40::/29
37 changes: 18 additions & 19 deletions internal/fields/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package fields

import (
"bufio"
_ "embed"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -35,7 +36,7 @@ type Validator struct {
disabledDependencyManagement bool

enabledAllowedIPCheck bool
allowedIPs map[string]struct{}
allowedCIDRs []*net.IPNet
}

// ValidatorOption represents an optional flag that can be passed to CreateValidatorForDataStream.
Expand Down Expand Up @@ -86,7 +87,7 @@ func CreateValidatorForDataStream(dataStreamRootPath string, opts ...ValidatorOp
}
}

v.allowedIPs = initializeAllowedIPsList()
v.allowedCIDRs = initializeAllowedCIDRsList()

v.Schema, err = loadFieldsForDataStream(dataStreamRootPath)
if err != nil {
Expand Down Expand Up @@ -118,20 +119,17 @@ func CreateValidatorForDataStream(dataStreamRootPath string, opts ...ValidatorOp
//go:embed _static/allowed_geo_ips.txt
var allowedGeoIPs string

func initializeAllowedIPsList() map[string]struct{} {
m := map[string]struct{}{
"0.0.0.0": {}, "255.255.255.255": {},
"0:0:0:0:0:0:0:0": {}, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff": {}, "::": {},
}
for _, ip := range strings.Split(allowedGeoIPs, "\n") {
ip = strings.Trim(ip, " \n\t")
if ip == "" {
continue
func initializeAllowedCIDRsList() (cidrs []*net.IPNet) {
s := bufio.NewScanner(strings.NewReader(allowedGeoIPs))
for s.Scan() {
_, cidr, err := net.ParseCIDR(s.Text())
if err != nil {
panic("invalid ip in _static/allowed_geo_ips.txt: " + s.Text())
}
m[ip] = struct{}{}
cidrs = append(cidrs, cidr)
}

return m
return cidrs
}

func loadFieldsForDataStream(dataStreamRootPath string) ([]FieldDefinition, error) {
Expand Down Expand Up @@ -442,17 +440,18 @@ func (v *Validator) parseElementValue(key string, definition FieldDefinition, va
// - 0.0.0.0 and 255.255.255.255 for IPv4
// - 0:0:0:0:0:0:0:0 and ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff for IPv6
func (v *Validator) isAllowedIPValue(s string) bool {
if _, found := v.allowedIPs[s]; found {
return true
}

ip := net.ParseIP(s)
if ip == nil {
return false
}

if ip.IsPrivate() || ip.IsLoopback() ||
ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {
for _, allowedCIDR := range v.allowedCIDRs {
if allowedCIDR.Contains(ip) {
return true
}
}

if ip.IsUnspecified() || ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {
return true
}

Expand Down
43 changes: 42 additions & 1 deletion internal/fields/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,42 @@ func Test_parseElementValue(t *testing.T) {
},
fail: true,
},
{
key: "ip in allowed list",
value: "1.128.3.4",
definition: FieldDefinition{
Type: "ip",
},
},
{
key: "ipv6 in allowed list",
value: "2a02:cf40:add:4002:91f2:a9b2:e09a:6fc6",
definition: FieldDefinition{
Type: "ip",
},
},
{
key: "unspecified ipv6",
value: "::",
definition: FieldDefinition{
Type: "ip",
},
},
{
key: "abbreviated ipv6 in allowed list with leading 0",
value: "2a02:cf40:0add:0::1",
definition: FieldDefinition{
Type: "ip",
},
},
{
key: "ip not in geoip database",
value: "8.8.8.8",
definition: FieldDefinition{
Type: "ip",
},
fail: true,
},
// text
{
key: "text",
Expand Down Expand Up @@ -266,7 +302,12 @@ func Test_parseElementValue(t *testing.T) {
},
},
} {
v := Validator{disabledDependencyManagement: true}
v := Validator{
disabledDependencyManagement: true,
enabledAllowedIPCheck: true,
allowedCIDRs: initializeAllowedCIDRsList(),
}

t.Run(test.key, func(t *testing.T) {
err := v.parseElementValue(test.key, test.definition, test.value)
if test.fail {
Expand Down