target(addr): add validation for ipv4, ipv6, and dns addr (#6038)

* target(addr): add validation for ipv4, ipv6, and dns addr
pull/6044/head
Irena Rindos 6 months ago committed by GitHub
parent 74e41e02df
commit 617caf2c64
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5,6 +5,8 @@ package target
import (
"context"
"net"
"regexp"
"strings"
"github.com/hashicorp/boundary/internal/db"
@ -31,6 +33,59 @@ var (
_ oplog.ReplayableMessage = (*Address)(nil)
)
var (
labelRegex = regexp.MustCompile(`^[a-zA-Z0-9-]{1,63}$`)
numbersRegex = regexp.MustCompile(`^\d+$`)
)
// DNS names consists of at least one label joined together by a "."
// Each label can consist of a-z 0-9 and "-" case insensitive
// A label cannot start or end with a "-"
// A label can be between 1 and 63 characters long
// The final label in the dns name cannot be all numeric
// See https://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax,_internationalization
func isValidDnsName(name string) bool {
// Trim any trailing dot, otherwise a name like "thing." will split to ["thing", ""] and return false for the empty label
name = strings.Trim(name, ".")
labels := strings.Split(name, ".")
if len(labels) == 0 {
return false
}
for i, label := range labels {
if len(label) < 1 || len(label) > 63 {
return false
}
if strings.HasPrefix(label, "-") || strings.HasSuffix(label, "-") {
return false
}
if !labelRegex.MatchString(label) {
return false
}
// Last label cannot be all numeric
if i == len(labels)-1 {
if numbersRegex.MatchString(label) {
return false
}
}
}
return true
}
// Current addresses supported are IPv4, IPv6 addresses
// or DNS names. More may be supported in the future.
func isValidAddress(address string) bool {
// Try to split host and port
_, _, splitErr := net.SplitHostPort(address)
if splitErr == nil {
return true
}
ip := net.ParseIP(address)
if ip != nil {
return true
}
return isValidDnsName(address)
}
// NewAddress creates a new in memory address. No options are
// currently supported.
func NewAddress(ctx context.Context, targetId, address string, _ ...Option) (*Address, error) {
@ -42,6 +97,9 @@ func NewAddress(ctx context.Context, targetId, address string, _ ...Option) (*Ad
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing address")
}
address = strings.TrimSpace(address)
if !isValidAddress(address) {
return nil, errors.New(ctx, errors.InvalidParameter, op, "invalid address")
}
t := &Address{
TargetAddress: &store.TargetAddress{
TargetId: targetId,

@ -40,7 +40,104 @@ func TestAddress_New(t *testing.T) {
wantErr: errors.InvalidParameter,
},
{
name: "valid",
name: "invalid-address-1",
args: args{
address: "-invalid.address",
targetId: "targ_0000000",
},
wantErr: errors.InvalidParameter,
},
{
name: "invalid-address-2",
args: args{
address: "invalid.1234",
targetId: "targ_0000000",
},
wantErr: errors.InvalidParameter,
},
{
name: "invalid-address-3",
args: args{
address: "invalid_address",
targetId: "targ_0000000",
},
wantErr: errors.InvalidParameter,
},
{
name: "invalid-address-4",
args: args{
address: "toolonglabeltoolonglabeltoolonglabeltoolonglabeltoolonglabeltoolonglabeltoolong.co",
targetId: "targ_0000000",
},
wantErr: errors.InvalidParameter,
},
{
name: "valid-dns-1",
args: args{
targetId: "targ_0000000",
address: "valid.",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "valid.",
},
},
},
{
name: "valid-dns-2",
args: args{
targetId: "targ_0000000",
address: "valid.address",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "valid.address",
},
},
},
{
name: "valid-dns-3",
args: args{
targetId: "targ_0000000",
address: "valid-address",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "valid-address",
},
},
},
{
name: "valid-dns-4",
args: args{
targetId: "targ_0000000",
address: "123-valid",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "123-valid",
},
},
},
{
name: "valid-dns-5",
args: args{
targetId: "targ_0000000",
address: "xn--d1acufc.xn--p1ai",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "xn--d1acufc.xn--p1ai",
},
},
},
{
name: "valid-ipv4",
args: args{
targetId: "targ_0000000",
address: "0.0.0.0",
@ -52,6 +149,45 @@ func TestAddress_New(t *testing.T) {
},
},
},
{
name: "valid-ipv4-port",
args: args{
targetId: "targ_0000000",
address: "0.0.0.0:35",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "0.0.0.0:35",
},
},
},
{
name: "valid-ipv6",
args: args{
targetId: "targ_0000000",
address: "0::0",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "0::0",
},
},
},
{
name: "valid-ipv6-port",
args: args{
targetId: "targ_0000000",
address: "0::0:45",
},
want: &target.Address{
TargetAddress: &store.TargetAddress{
TargetId: "targ_0000000",
Address: "0::0:45",
},
},
},
}
for _, tt := range tests {
tt := tt

Loading…
Cancel
Save