(fix) Flaky BoxOAuth detector test (#4199)
* moved Generate random Password func to utils to be used by multiple detectors test. * fixed spelling issue --------- Co-authored-by: Amaan Ullah <[email protected]>
This commit is contained in:
co-authored by
Amaan Ullah
parent
bda0787e98
commit
5eb357dd1c
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"math/big"
|
||||
mrand "math/rand"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -70,3 +71,65 @@ func SliceContainsString(origTargetString string, stringSlice []string, ignoreCa
|
||||
}
|
||||
return false, "", 0
|
||||
}
|
||||
|
||||
// GoFakeIt Password generator does not guarantee inclusion of characters.
|
||||
// Using a custom random password generator with guaranteed inclusions (atleast) of lower, upper, numeric and special characters
|
||||
func GenerateRandomPassword(lower, upper, numeric, special bool, length int) string {
|
||||
if length < 1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var password []rune
|
||||
var required []rune
|
||||
var allowed []rune
|
||||
|
||||
lowerChars := []rune("abcdefghijklmnopqrstuvwxyz")
|
||||
upperChars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
specialChars := []rune("!@#$%^&*()-_=+[]{}|;:',.<>?/")
|
||||
numberChars := []rune("0123456789")
|
||||
|
||||
// Ensure inclusion from each requested category
|
||||
if lower {
|
||||
rand, _ := rand.Int(rand.Reader, big.NewInt(int64(len(lowerChars))))
|
||||
ch := lowerChars[rand.Int64()]
|
||||
required = append(required, ch)
|
||||
allowed = append(allowed, lowerChars...)
|
||||
}
|
||||
if upper {
|
||||
rand, _ := rand.Int(rand.Reader, big.NewInt(int64(len(upperChars))))
|
||||
ch := upperChars[rand.Int64()]
|
||||
required = append(required, ch)
|
||||
allowed = append(allowed, upperChars...)
|
||||
}
|
||||
if numeric {
|
||||
rand, _ := rand.Int(rand.Reader, big.NewInt(int64(len(numberChars))))
|
||||
ch := numberChars[rand.Int64()]
|
||||
required = append(required, ch)
|
||||
allowed = append(allowed, numberChars...)
|
||||
}
|
||||
if special {
|
||||
rand, _ := rand.Int(rand.Reader, big.NewInt(int64(len(specialChars))))
|
||||
ch := specialChars[rand.Int64()]
|
||||
required = append(required, ch)
|
||||
allowed = append(allowed, specialChars...)
|
||||
}
|
||||
|
||||
if len(allowed) == 0 {
|
||||
return "" // No character sets enabled
|
||||
}
|
||||
|
||||
// Fill the rest of the password
|
||||
for i := 0; i < length-len(required); i++ {
|
||||
rand, _ := rand.Int(rand.Reader, big.NewInt(int64(len(allowed))))
|
||||
ch := allowed[rand.Int64()]
|
||||
password = append(password, ch)
|
||||
}
|
||||
|
||||
// Combine required and random characters, then shuffle
|
||||
password = append(password, required...)
|
||||
mrand.Shuffle(len(password), func(i, j int) {
|
||||
password[i], password[j] = password[j], password[i]
|
||||
})
|
||||
|
||||
return string(password)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func TestAddItem(t *testing.T) {
|
||||
@@ -194,3 +195,85 @@ func TestSliceContainsString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRandomPassword_Length(t *testing.T) {
|
||||
pass := GenerateRandomPassword(true, true, true, true, 16)
|
||||
if len(pass) != 16 {
|
||||
t.Errorf("expected length 16, got %d", len(pass))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRandomPassword_Empty(t *testing.T) {
|
||||
pass := GenerateRandomPassword(false, false, false, false, 10)
|
||||
if pass != "" {
|
||||
t.Errorf("expected empty string, got %q", pass)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRandomPassword_RequiredSets(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
lower bool
|
||||
upper bool
|
||||
numeric bool
|
||||
special bool
|
||||
}{
|
||||
{"lower only", true, false, false, false},
|
||||
{"upper only", false, true, false, false},
|
||||
{"numeric only", false, false, true, false},
|
||||
{"special only", false, false, false, true},
|
||||
{"all", true, true, true, true},
|
||||
{"lower+upper", true, true, false, false},
|
||||
{"lower+numeric", true, false, true, false},
|
||||
{"upper+special", false, true, false, true},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
pass := GenerateRandomPassword(tc.lower, tc.upper, tc.numeric, tc.special, 12)
|
||||
if len(pass) != 12 {
|
||||
t.Errorf("expected length 12, got %d", len(pass))
|
||||
}
|
||||
if tc.lower && !contains(pass, unicode.IsLower) {
|
||||
t.Errorf("expected at least one lowercase letter")
|
||||
}
|
||||
if tc.upper && !contains(pass, unicode.IsUpper) {
|
||||
t.Errorf("expected at least one uppercase letter")
|
||||
}
|
||||
if tc.numeric && !contains(pass, unicode.IsDigit) {
|
||||
t.Errorf("expected at least one digit")
|
||||
}
|
||||
if tc.special && !containsSpecial(pass) {
|
||||
t.Errorf("expected at least one special character")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRandomPassword_ShortLength(t *testing.T) {
|
||||
pass := GenerateRandomPassword(true, true, true, true, 0)
|
||||
if pass != "" {
|
||||
t.Errorf("expected empty string for length 0, got %q", pass)
|
||||
}
|
||||
}
|
||||
|
||||
func contains(s string, fn func(rune) bool) bool {
|
||||
for _, r := range s {
|
||||
if fn(r) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func containsSpecial(s string) bool {
|
||||
specials := "!@#$%^&*()-_=+[]{}|;:',.<>?/"
|
||||
for _, r := range s {
|
||||
for _, sr := range specials {
|
||||
if r == sr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -7,15 +7,15 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v7"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick"
|
||||
)
|
||||
|
||||
var (
|
||||
clientId = gofakeit.Password(true, true, true, false, false, 32)
|
||||
clientSecret = gofakeit.Password(true, true, true, false, false, 32)
|
||||
invalidClientSecret = gofakeit.Password(true, true, true, true, false, 32)
|
||||
clientId = common.GenerateRandomPassword(true, true, true, false, 32)
|
||||
clientSecret = common.GenerateRandomPassword(true, true, true, false, 32)
|
||||
invalidClientSecret = common.GenerateRandomPassword(true, true, true, true, 32)
|
||||
)
|
||||
|
||||
func TestBoxOauth_Pattern(t *testing.T) {
|
||||
|
||||
@@ -3,66 +3,15 @@ package snowflake
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v7"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick"
|
||||
)
|
||||
|
||||
// GoFakeIt Password generator does not guarantee inclusion of characters.
|
||||
// Using a custom Password gennerator with guaranteed inclusions (atleast) of lower, upper and numeric characters
|
||||
func generatePassword(lower, upper, numeric bool, length int) string {
|
||||
if length < 1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var password []rune
|
||||
var required []rune
|
||||
var allowed []rune
|
||||
|
||||
lowerChars := []rune("abcdefghijklmnopqrstuvwxyz")
|
||||
upperChars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
numberChars := []rune("0123456789")
|
||||
|
||||
// Ensure inclusion from each requested category
|
||||
if lower {
|
||||
ch := lowerChars[rand.Intn(len(lowerChars))]
|
||||
required = append(required, ch)
|
||||
allowed = append(allowed, lowerChars...)
|
||||
}
|
||||
if upper {
|
||||
ch := upperChars[rand.Intn(len(upperChars))]
|
||||
required = append(required, ch)
|
||||
allowed = append(allowed, upperChars...)
|
||||
}
|
||||
if numeric {
|
||||
ch := numberChars[rand.Intn(len(numberChars))]
|
||||
required = append(required, ch)
|
||||
allowed = append(allowed, numberChars...)
|
||||
}
|
||||
|
||||
if len(allowed) == 0 {
|
||||
return "" // No character sets enabled
|
||||
}
|
||||
|
||||
// Fill the rest of the password
|
||||
for i := 0; i < length-len(required); i++ {
|
||||
ch := allowed[rand.Intn(len(allowed))]
|
||||
password = append(password, ch)
|
||||
}
|
||||
|
||||
// Combine required and random characters, then shuffle
|
||||
password = append(password, required...)
|
||||
rand.Shuffle(len(password), func(i, j int) {
|
||||
password[i], password[j] = password[j], password[i]
|
||||
})
|
||||
|
||||
return string(password)
|
||||
}
|
||||
|
||||
func TestSnowflake_Pattern(t *testing.T) {
|
||||
|
||||
validAccount := "tuacoip-zt74995"
|
||||
@@ -71,7 +20,7 @@ func TestSnowflake_Pattern(t *testing.T) {
|
||||
validUsername := gofakeit.Username()
|
||||
invalidUsername := "[email protected]" // special characters not allowed
|
||||
|
||||
validPassword := generatePassword(true, true, true, 10)
|
||||
validPassword := common.GenerateRandomPassword(true, true, true, false, 10)
|
||||
invalidPassword := "!12" // invalid length
|
||||
|
||||
d := Scanner{}
|
||||
|
||||
Reference in New Issue
Block a user