mirror of
https://github.com/cloudflare/cloudflared.git
synced 2026-10-12 02:12:14 +00:00
This prevents users from abusing `--allowed-mail` policies by limiting the nr. of rules to 100 and defining a max per rule of 320 bytes. Validation errors now identify only the rule position and category, preventing recipient values from appearing in logs. Parsing also stops once limits are exceeded while preserving normalisation and deduplication.
147 lines
5.7 KiB
Go
147 lines
5.7 KiB
Go
package quicktunnelauth
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestValidateQuickTunnelAllowedMail(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
values []string
|
|
expectedEmails []string
|
|
expectedDomains []string
|
|
}{
|
|
{name: "multiple without spaces", values: []string{"[email protected],[email protected]"}, expectedEmails: []string{"[email protected]", "[email protected]"}},
|
|
{name: "multiple with consistent spaces", values: []string{"[email protected], [email protected]"}, expectedEmails: []string{"[email protected]", "[email protected]"}},
|
|
{name: "multiple with inconsistent spaces", values: []string{" [email protected],[email protected] , [email protected] "}, expectedEmails: []string{"[email protected]", "[email protected]", "[email protected]"}},
|
|
{name: "single with leading spaces", values: []string{" [email protected]"}, expectedEmails: []string{"[email protected]"}},
|
|
{name: "single with trailing spaces", values: []string{"[email protected] "}, expectedEmails: []string{"[email protected]"}},
|
|
{name: "single with surrounding spaces", values: []string{" [email protected] "}, expectedEmails: []string{"[email protected]"}},
|
|
{name: "repeated flags", values: []string{"[email protected]", "[email protected],*@Example.org"}, expectedEmails: []string{"[email protected]", "[email protected]"}, expectedDomains: []string{"example.org"}},
|
|
{name: "deduplicated", values: []string{"[email protected],[email protected]", "*@Example.org,*@example.org"}, expectedEmails: []string{"[email protected]"}, expectedDomains: []string{"example.org"}},
|
|
{name: "punycode IDN", values: []string{"[email protected],*@xn--fiqs8s"}, expectedEmails: []string{"[email protected]"}, expectedDomains: []string{"xn--fiqs8s"}},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
emails, domains, err := validateQuickTunnelAllowedMail(test.values)
|
|
require.NoError(t, err)
|
|
assert.Len(t, emails, len(test.expectedEmails))
|
|
assert.Len(t, domains, len(test.expectedDomains))
|
|
for _, email := range test.expectedEmails {
|
|
assert.Contains(t, emails, email)
|
|
}
|
|
for _, domain := range test.expectedDomains {
|
|
assert.Contains(t, domains, domain)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateQuickTunnelAllowedMailRejectsMalformedEntries(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
values []string
|
|
}{
|
|
{name: "empty"},
|
|
{name: "blank", values: []string{" , "}},
|
|
{name: "display name", values: []string{"User <[email protected]>"}},
|
|
{name: "missing wildcard at", values: []string{"*example.com"}},
|
|
{name: "double at", values: []string{"user@@example.com"}},
|
|
{name: "invalid exact domain", values: []string{"[email protected]"}},
|
|
{name: "empty wildcard domain", values: []string{"*@"}},
|
|
{name: "empty domain label", values: []string{"*@example..com"}},
|
|
{name: "leading domain hyphen", values: []string{"*@-example.com"}},
|
|
{name: "trailing domain hyphen", values: []string{"*@example-.com"}},
|
|
{name: "invalid domain character", values: []string{"*@exam_ple.com"}},
|
|
{name: "unicode IDN", values: []string{"jim@something.\u4e2d\u56fd"}},
|
|
{name: "long domain label", values: []string{"*@" + strings.Repeat("a", 64) + ".com"}},
|
|
{name: "long domain", values: []string{"*@" + strings.Repeat("a.", 126) + "aa"}},
|
|
{name: "domain path", values: []string{"*@example.com/path"}},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
_, _, err := validateQuickTunnelAllowedMail(test.values)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateQuickTunnelAllowedMailRejectsEmptyRuleWithoutLeakingValues(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
values := []string{"[email protected],,[email protected]"}
|
|
_, _, err := validateQuickTunnelAllowedMail(values)
|
|
require.EqualError(t, err, "allowed mail rule 2 is empty")
|
|
assert.NotContains(t, err.Error(), "example.com")
|
|
}
|
|
|
|
func TestValidateQuickTunnelAllowedMailReportsInvalidRule(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
values []string
|
|
expectedError string
|
|
}{
|
|
{name: "email", values: []string{"[email protected]", "[email protected]/path"}, expectedError: "allowed mail rule 2 is not a valid email address"},
|
|
{name: "wildcard", values: []string{"[email protected]", "*@example.com/path"}, expectedError: "allowed mail rule 2 has an invalid wildcard domain"},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
_, _, err := validateQuickTunnelAllowedMail(test.values)
|
|
require.EqualError(t, err, test.expectedError)
|
|
for _, value := range test.values {
|
|
assert.NotContains(t, err.Error(), value)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateQuickTunnelAllowedMailBoundsInput(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tooManyRules := make([]string, quickTunnelAuthMaxAllowedMailRules+1)
|
|
for index := range tooManyRules {
|
|
tooManyRules[index] = "[email protected]"
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
values []string
|
|
expectedError string
|
|
}{
|
|
{
|
|
name: "too many rules",
|
|
values: tooManyRules,
|
|
expectedError: fmt.Sprintf("allowed mail rules exceed the %d-entry limit", quickTunnelAuthMaxAllowedMailRules),
|
|
},
|
|
{
|
|
name: "rule too long before trimming",
|
|
values: []string{strings.Repeat(" ", quickTunnelAuthMaxAllowedMailRuleBytes) + "a"},
|
|
expectedError: fmt.Sprintf("allowed mail rule 1 exceeds the %d-byte limit", quickTunnelAuthMaxAllowedMailRuleBytes),
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
_, _, err := validateQuickTunnelAllowedMail(test.values)
|
|
require.EqualError(t, err, test.expectedError)
|
|
})
|
|
}
|
|
}
|