diff --git a/pkg/detectors/abstract/abstract_test.go b/pkg/detectors/abstract/abstract_test.go index 647c1e564..1a1172c50 100644 --- a/pkg/detectors/abstract/abstract_test.go +++ b/pkg/detectors/abstract/abstract_test.go @@ -2,20 +2,15 @@ package abstract import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "qwerty12345iugt67s7a7sa0akhsxz82" - invalidPattern = "zxcvbr12345iugt67s7a7sa0akhsXz820" -) - func TestAbstract_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,58 @@ func TestAbstract_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("abstract token = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to abstract API + [DEBUG] Using API_KEY=oxpf4a93fjovt0v1z6lltcbcizlrml98 + [INFO] Response received: 200 OK + `, + want: []string{"oxpf4a93fjovt0v1z6lltcbcizlrml98"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("abstract token keyword is not close to the real token = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {abstract} + {abstract AQAAABAAA 5422358j60yxo9nc0dbpxby602tsxd6j} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"5422358j60yxo9nc0dbpxby602tsxd6j"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("abstract = '%s'", invalidPattern), - want: nil, + name: "valid pattern - two keys", + input: ` + [INFO] Sending request to abstract API + [DEBUG] Using API_KEY=oxpf4a93fjovt0v1z6lltcbcizlrml98 + [Error] Response received: 401 UnAuthorized + [INFO] Sending request to abstract API + [DEBUG] Using API_KEY=muytrs09876iugt67s7a7sa0akhsxz82 + [INFO] Response received: 200 OK + `, + want: []string{"oxpf4a93fjovt0v1z6lltcbcizlrml98", "muytrs09876iugt67s7a7sa0akhsxz82"}, + }, + { + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to abstract API + [INFO] Processing request + [Info] Response received: 200 OK + [DEBUG] Used API_KEY=oxpf4a93fjovt0v1z6lltcbcizlrml98 + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to abstract API + [DEBUG] Using API_KEY=zxcvbr12345iugt67s7a7sa0akhsXz820 + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -46,22 +80,15 @@ func TestAbstract_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +100,7 @@ func TestAbstract_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/abuseipdb/abuseipdb_test.go b/pkg/detectors/abuseipdb/abuseipdb_test.go index eec2bf0fd..d0fa8244c 100644 --- a/pkg/detectors/abuseipdb/abuseipdb_test.go +++ b/pkg/detectors/abuseipdb/abuseipdb_test.go @@ -2,20 +2,15 @@ package abuseipdb import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "123abcdef456ghijkl789mnopqr012stuvwx3455123abcdef456ghijkl789mnopqr012stuvwx3455" - invalidPattern = "123abcdef456Ghijkl789mnopqr012stuvwx3455123abcdef456ghijkl789mnopqr012stuvwX" -) - func TestAbuseipdb_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAbuseipdb_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("abuseipdb token = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to abuseipdb API + [DEBUG] Using API_KEY=o8oqti3tghu2xic76ii4t7jb9bxuzd4200j1yrkdjl6s8834hx4dgz1wwo90diqraakjd13sljcjkfnf + [INFO] Response received: 200 OK + `, + want: []string{"o8oqti3tghu2xic76ii4t7jb9bxuzd4200j1yrkdjl6s8834hx4dgz1wwo90diqraakjd13sljcjkfnf"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("abuseipdb token keyword is not close to the real token = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {abuseipdb} + {abuseipdb AQAAABAAA zgtj0q3v38u4pthc6nmy02n60bj244u5o9j47ln1jlue5mxzaasfi29x4dzcbxroawvkm26thtr61066} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"zgtj0q3v38u4pthc6nmy02n60bj244u5o9j47ln1jlue5mxzaasfi29x4dzcbxroawvkm26thtr61066"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("abuseipdb = '%s'", invalidPattern), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to abuseipdb API + [INFO] Processing request + [Info] Response received: 200 OK + [DEBUG] Used API_KEY=o8oqti3tghu2xic76ii4t7jb9bxuzd4200j1yrkdjl6s8834hx4dgz1wwo90diqraakjd13sljcjkfnf + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to abuseipdb API + [DEBUG] Using API_KEY=7e4abcdef456Ghijkl789mnopqr012stuvwx3455123abcdef456ghijkl789mnopqr012stuvwX + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAbuseipdb_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAbuseipdb_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/abyssale/abyssale_test.go b/pkg/detectors/abyssale/abyssale_test.go index 3016149c7..f57e86781 100644 --- a/pkg/detectors/abyssale/abyssale_test.go +++ b/pkg/detectors/abyssale/abyssale_test.go @@ -2,20 +2,15 @@ package abyssale import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "123abcDEF456ghiJKL789mnoPQR012stuVWX3456" - invalidPattern = "123abcDEF456ghiJKL789mnoPQR012stuVWX" -) - func TestAbyssale_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAbyssale_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("abyssale token = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to abyssale API + [DEBUG] Using API_KEY=rWE8I0axy6Fvw40RE8tsNS3L7zBU5vAhEnW4hq9G + [INFO] Response received: 200 OK + `, + want: []string{"rWE8I0axy6Fvw40RE8tsNS3L7zBU5vAhEnW4hq9G"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("abyssale token keyword is not close to the real token = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {abyssale} + {abyssale AQAAABAAA xTiPNSDg6JjzG8fWoLb8JlE8SBcMKkCx2fZLZD91} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"xTiPNSDg6JjzG8fWoLb8JlE8SBcMKkCx2fZLZD91"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("abyssale = '%s'", invalidPattern), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to abyssale API + [INFO] Processing request + [Info] Response received: 200 OK + [DEBUG] Used API_KEY=rWE8I0axy6Fvw40RE8tsNS3L7zBU5vAhEnW4hq9G + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to abyssale API + [DEBUG] Using API_KEY=rWE8_0axy6Fvw40RE8tsNS3L7zBU5vAhEnW4hq9G + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAbyssale_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAbyssale_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/accuweather/v1/accuweather_test.go b/pkg/detectors/accuweather/v1/accuweather_test.go index 2dc772b66..0836c4dfb 100644 --- a/pkg/detectors/accuweather/v1/accuweather_test.go +++ b/pkg/detectors/accuweather/v1/accuweather_test.go @@ -2,21 +2,15 @@ package accuweather import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "DqFtwc490oPc%xaE67sBSF741M56%sd091A" - invalidPattern = "DqFtwc490oPc%xaE67sBSF741M56=sd091A" - validPatternLowEntropy = "DsFtwfaEsAPS%eaEsaESEsFesfMsfMsDmdA" -) - func TestAccuWeather_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -27,24 +21,55 @@ func TestAccuWeather_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("accuweather token = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to accuweather API + [DEBUG] Using API_KEY=WAgP6m4gYc1qe%HnjWAAF5HBKL%i6kwrsbD + [INFO] Response received: 200 OK + `, + want: []string{"WAgP6m4gYc1qe%HnjWAAF5HBKL%i6kwrsbD"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("accuweather token keyword is not close to the real token = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {accuweather} + {accuweather AQAAABAAA ErOAU9rTSuX6IfHFGsJbpK3bCC1jIEX%gtj} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"ErOAU9rTSuX6IfHFGsJbpK3bCC1jIEX%gtj"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("accuweather = '%s'", invalidPattern), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to accuweather API + [INFO] Processing request + [Info] Response received: 200 OK + [DEBUG] Used API_KEY=WAgP6m4gYc1qe%HnjWAAF5HBKL%i6kwrsbD + `, + want: nil, }, { - name: "valid pattern - Shannon entropy below threshold", - input: fmt.Sprintf("accuweather = '%s'", validPatternLowEntropy), - want: nil, + name: "invalid pattern", + input: ` + [INFO] Sending request to accuweather API + [DEBUG] Using API_KEY=WAgP6m4gYc1qe$HnjWAAF5HBKL%i6kwrsbD + [Error] Response received: 400 BadRequest + `, + want: nil, + }, + { + name: "valid pattern - Shannon entropy below threshold", + input: ` + [INFO] Sending request to accuweather API + [DEBUG] Using API_KEY=WAAP6A4gYA1qA%HAaWAAFAHBAL%a6kwwwbD + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -52,22 +77,15 @@ func TestAccuWeather_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -79,6 +97,7 @@ func TestAccuWeather_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/accuweather/v2/accuweather_test.go b/pkg/detectors/accuweather/v2/accuweather_test.go index b4c309f54..85e65c730 100644 --- a/pkg/detectors/accuweather/v2/accuweather_test.go +++ b/pkg/detectors/accuweather/v2/accuweather_test.go @@ -2,20 +2,15 @@ package accuweather import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "dqftwc490oPcxae67sBSF741M56d091a" - invalidPattern = "dqftwc49%oPcxae67sBSF741M56f091a" -) - func TestAccuWeather_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAccuWeather_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("accuweather token = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to accuweather API + [DEBUG] Using API_KEY=Qh6DP6Zf7vHtmnDDsbS219qcz4d883Y9 + [INFO] Response received: 200 OK + `, + want: []string{"Qh6DP6Zf7vHtmnDDsbS219qcz4d883Y9"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("accuweather token keyword is not close to the real token = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {accuweather} + {accuweather AQAAABAAA BJDD9bYh8bR586Wcw3F1lvkUYy3RZZbD} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"BJDD9bYh8bR586Wcw3F1lvkUYy3RZZbD"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("accuweather = '%s'", invalidPattern), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to accuweather API + [INFO] Processing request + [Info] Response received: 200 OK + [DEBUG] Used API_KEY=Qh6DP6Zf7vHtmnDDsbS219qcz4d883Y9 + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to accuweather API + [DEBUG] Using API_KEY=Qh6DP6Zf7vHtm@DDsbS219qcz4d883Y9 + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAccuWeather_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAccuWeather_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/adafruitio/adafruitio_integration_test.go b/pkg/detectors/adafruitio/adafruitio_integration_test.go new file mode 100644 index 000000000..82702d0e9 --- /dev/null +++ b/pkg/detectors/adafruitio/adafruitio_integration_test.go @@ -0,0 +1,167 @@ +//go:build detectors +// +build detectors + +package adafruitio + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" + "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" +) + +func TestAdafruitIO_FromChunk(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors1") + if err != nil { + t.Fatalf("could not get test secrets from GCP: %s", err) + } + secret := testSecrets.MustGetField("ADAFRUITIO") + inactiveSecret := testSecrets.MustGetField("ADAFRUITIO_INACTIVE") + + type args struct { + ctx context.Context + data []byte + verify bool + } + tests := []struct { + name string + s Scanner + args args + want []detectors.Result + wantErr bool + }{ + { + name: "found, verified", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within", secret)), + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_AdafruitIO, + Verified: true, + }, + }, + wantErr: false, + }, + { + name: "found, real secrets, verification error due to timeout", + s: Scanner{client: common.SaneHttpClientTimeOut(10 * time.Microsecond)}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within", secret)), + verify: true, + }, + want: func() []detectors.Result { + r := detectors.Result{ + DetectorType: detectorspb.DetectorType_AdafruitIO, + Verified: false, + } + r.SetVerificationError(context.DeadlineExceeded) + return []detectors.Result{r} + }(), + wantErr: false, + }, + { + name: "found, real secrets, verification error due to unexpected api surface", + s: Scanner{client: common.ConstantResponseHttpClient(500, "{}")}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within", secret)), + verify: true, + }, + want: func() []detectors.Result { + r := detectors.Result{ + DetectorType: detectorspb.DetectorType_AdafruitIO, + Verified: false, + } + r.SetVerificationError(fmt.Errorf("unexpected HTTP response status 500")) + return []detectors.Result{r} + }(), + wantErr: false, + }, + { + name: "found, unverified", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within but not valid", inactiveSecret)), // the secret would satisfy the regex but not pass validation + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_AdafruitIO, + Verified: false, + }, + }, + wantErr: false, + }, + { + name: "not found", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte("You cannot find the secret within"), + verify: true, + }, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.s.FromData(tt.args.ctx, tt.args.verify, tt.args.data) + if (err != nil) != tt.wantErr { + t.Errorf("AdafruitIO.FromData() error = %v, wantErr %v", err, tt.wantErr) + return + } + for i := range got { + if len(got[i].Raw) == 0 { + t.Fatalf("no raw secret present: \n %+v", got[i]) + } + gotErr := "" + if got[i].VerificationError() != nil { + gotErr = got[i].VerificationError().Error() + } + wantErr := "" + if tt.want[i].VerificationError() != nil { + wantErr = tt.want[i].VerificationError().Error() + } + if gotErr != wantErr { + t.Fatalf("wantVerificationError = %v, verification error = %v", tt.want[i].VerificationError(), got[i].VerificationError()) + } + } + ignoreOpts := cmpopts.IgnoreFields(detectors.Result{}, "Raw", "RawV2", "verificationError") + if diff := cmp.Diff(got, tt.want, ignoreOpts); diff != "" { + t.Errorf("AdafruitIO.FromData() %s diff: (-got +want)\n%s", tt.name, diff) + } + }) + } +} + +func BenchmarkFromData(benchmark *testing.B) { + ctx := context.Background() + s := Scanner{} + for name, data := range detectors.MustGetBenchmarkData() { + benchmark.Run(name, func(b *testing.B) { + b.ResetTimer() + for n := 0; n < b.N; n++ { + _, err := s.FromData(ctx, false, data) + if err != nil { + b.Fatal(err) + } + } + }) + } +} diff --git a/pkg/detectors/adafruitio/adafruitio_test.go b/pkg/detectors/adafruitio/adafruitio_test.go index 82702d0e9..043bb8ef7 100644 --- a/pkg/detectors/adafruitio/adafruitio_test.go +++ b/pkg/detectors/adafruitio/adafruitio_test.go @@ -1,167 +1,92 @@ -//go:build detectors -// +build detectors - package adafruitio import ( "context" - "fmt" "testing" - "time" "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/require" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" - "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" + "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -func TestAdafruitIO_FromChunk(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) - defer cancel() - testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors1") - if err != nil { - t.Fatalf("could not get test secrets from GCP: %s", err) - } - secret := testSecrets.MustGetField("ADAFRUITIO") - inactiveSecret := testSecrets.MustGetField("ADAFRUITIO_INACTIVE") +func TestAdafruitio_Pattern(t *testing.T) { + d := Scanner{} + ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) - type args struct { - ctx context.Context - data []byte - verify bool - } tests := []struct { - name string - s Scanner - args args - want []detectors.Result - wantErr bool + name string + input string + want []string }{ { - name: "found, verified", - s: Scanner{}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within", secret)), - verify: true, - }, - want: []detectors.Result{ - { - DetectorType: detectorspb.DetectorType_AdafruitIO, - Verified: true, - }, - }, - wantErr: false, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using API_KEY=aio_VxEqGaqgMgZej3DceezbBy03eWyW + [INFO] Response received: 200 OK + `, + want: []string{"aio_VxEqGaqgMgZej3DceezbBy03eWyW"}, }, { - name: "found, real secrets, verification error due to timeout", - s: Scanner{client: common.SaneHttpClientTimeOut(10 * time.Microsecond)}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within", secret)), - verify: true, - }, - want: func() []detectors.Result { - r := detectors.Result{ - DetectorType: detectorspb.DetectorType_AdafruitIO, - Verified: false, - } - r.SetVerificationError(context.DeadlineExceeded) - return []detectors.Result{r} - }(), - wantErr: false, + name: "valid pattern - xml", + input: ` + + GLOBAL + {adafruitio} + {AQAAABAAA aio_cQD77DF9SgsYbgWcxJbpLOlR5emX} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"aio_cQD77DF9SgsYbgWcxJbpLOlR5emX"}, }, { - name: "found, real secrets, verification error due to unexpected api surface", - s: Scanner{client: common.ConstantResponseHttpClient(500, "{}")}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within", secret)), - verify: true, - }, - want: func() []detectors.Result { - r := detectors.Result{ - DetectorType: detectorspb.DetectorType_AdafruitIO, - Verified: false, - } - r.SetVerificationError(fmt.Errorf("unexpected HTTP response status 500")) - return []detectors.Result{r} - }(), - wantErr: false, - }, - { - name: "found, unverified", - s: Scanner{}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a adafruitio secret %s within but not valid", inactiveSecret)), // the secret would satisfy the regex but not pass validation - verify: true, - }, - want: []detectors.Result{ - { - DetectorType: detectorspb.DetectorType_AdafruitIO, - Verified: false, - }, - }, - wantErr: false, - }, - { - name: "not found", - s: Scanner{}, - args: args{ - ctx: context.Background(), - data: []byte("You cannot find the secret within"), - verify: true, - }, - want: nil, - wantErr: false, + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using API_KEY=aio_VxEqGaqgMgZej3DceezbBy03eWyWa + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.s.FromData(tt.args.ctx, tt.args.verify, tt.args.data) - if (err != nil) != tt.wantErr { - t.Errorf("AdafruitIO.FromData() error = %v, wantErr %v", err, tt.wantErr) + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) + if len(matchedDetectors) == 0 { + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } - for i := range got { - if len(got[i].Raw) == 0 { - t.Fatalf("no raw secret present: \n %+v", got[i]) - } - gotErr := "" - if got[i].VerificationError() != nil { - gotErr = got[i].VerificationError().Error() - } - wantErr := "" - if tt.want[i].VerificationError() != nil { - wantErr = tt.want[i].VerificationError().Error() - } - if gotErr != wantErr { - t.Fatalf("wantVerificationError = %v, verification error = %v", tt.want[i].VerificationError(), got[i].VerificationError()) - } - } - ignoreOpts := cmpopts.IgnoreFields(detectors.Result{}, "Raw", "RawV2", "verificationError") - if diff := cmp.Diff(got, tt.want, ignoreOpts); diff != "" { - t.Errorf("AdafruitIO.FromData() %s diff: (-got +want)\n%s", tt.name, diff) - } - }) - } -} -func BenchmarkFromData(benchmark *testing.B) { - ctx := context.Background() - s := Scanner{} - for name, data := range detectors.MustGetBenchmarkData() { - benchmark.Run(name, func(b *testing.B) { - b.ResetTimer() - for n := 0; n < b.N; n++ { - _, err := s.FromData(ctx, false, data) - if err != nil { - b.Fatal(err) + results, err := d.FromData(context.Background(), false, []byte(test.input)) + require.NoError(t, err) + + if len(results) != len(test.want) { + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) + return + } + + actual := make(map[string]struct{}, len(results)) + for _, r := range results { + if len(r.RawV2) > 0 { + actual[string(r.RawV2)] = struct{}{} + } else { + actual[string(r.Raw)] = struct{}{} } } + + expected := make(map[string]struct{}, len(test.want)) + for _, v := range test.want { + expected[v] = struct{}{} + } + + if diff := cmp.Diff(expected, actual); diff != "" { + t.Errorf("%s diff: (-want +got)\n%s", test.name, diff) + } }) } } diff --git a/pkg/detectors/adobeio/adobeio_test.go b/pkg/detectors/adobeio/adobeio_test.go index 649096da0..1c854f78e 100644 --- a/pkg/detectors/adobeio/adobeio_test.go +++ b/pkg/detectors/adobeio/adobeio_test.go @@ -2,20 +2,15 @@ package adobeio import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "zxcv0987mnbv1234poiu6749gtnrfv54/WDcv0981Mn.B" - invalidPattern = "Rzxc#0987$%bv1234poiu6749gtnrfv54" -) - func TestAdobeIO_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,48 @@ func TestAdobeIO_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("adobe = '%s'", validPattern), - want: []string{"zxcv0987mnbv1234poiu6749gtnrfv54WDcv0981Mn.B"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the adobe API + [DEBUG] Using adobe KEY=zoaw0c0m50m0hz2h1fm21y4tqfyl7ifi + [DEBUG] Using adobe ID=qCRbiIy1NJaW + [INFO] Response received: 200 OK + `, + want: []string{"zoaw0c0m50m0hz2h1fm21y4tqfyl7ifiqCRbiIy1NJaW"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("adobe keyword is not close to the real id and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {adobe ftd7hkeafk0q} + {adobe AQAAABAAA siybmtkgho9nsgjhng5yhp92wnir2a9t} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"siybmtkgho9nsgjhng5yhp92wnir2a9tftd7hkeafk0q"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("adobe%s", invalidPattern), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to the adobe API + [DEBUG] Using KEY=zoaw0c0m50m0hz2h1fm21y4tqfyl7ifi + [DEBUG] Using ID=qCRbiIy1NJaW + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the adobe API + [DEBUG] Using adobe KEY=Rzxc#0987$%bv1234poiu6749gtnrfv54 + [DEBUG] Using adobe ID=qCRbiIy1NJaW + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -46,22 +70,15 @@ func TestAdobeIO_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +90,7 @@ func TestAdobeIO_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/adzuna/adzuna_test.go b/pkg/detectors/adzuna/adzuna_test.go index 83dd82037..cd8a04bd1 100644 --- a/pkg/detectors/adzuna/adzuna_test.go +++ b/pkg/detectors/adzuna/adzuna_test.go @@ -2,21 +2,15 @@ package adzuna import ( "context" - "fmt" - "strings" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "asdf0987mnbv1234qsxojb6ygb2wsx0o/qsc0f098" - invalidPattern = "as#f0987mnbv1234^sxojb6ygb2wsx0o/qsc0f098" -) - func TestAdzuna_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -27,29 +21,66 @@ func TestAdzuna_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("adzuna = '%s'", validPattern), - want: []string{"asdf0987mnbv1234qsxojb6ygb2wsx0oqsc0f098"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the adzuna API + [DEBUG] Using adzuna KEY=smcud4y6elxx7u6q58ewwv8rq01hpi3f + [DEBUG] Using adzuna ID=cxu9w2g6 + [INFO] Response received: 200 OK + `, + want: []string{"smcud4y6elxx7u6q58ewwv8rq01hpi3fcxu9w2g6"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("adzuna keyword is not close to the real id and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {adzuna svkit0wx} + {adzuna AQAAABAAA atubvgvpd6jjo0ac1wjianofnpgr24ac} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"atubvgvpd6jjo0ac1wjianofnpgr24acsvkit0wx"}, }, { - name: "valid pattern - only key", - input: fmt.Sprintf("adzuna %s", strings.Split(validPattern, "/")[0]), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to the adzuna API + [DEBUG] Using KEY=smcud4y6elxx7u6q58ewwv8rq01hpi3f + [DEBUG] Using ID=cxu9w2g6 + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "valid pattern - only id", - input: fmt.Sprintf("adzuna %s", strings.Split(validPattern, "/")[1]), - want: nil, + name: "valid pattern - only key", + input: ` + [INFO] Sending request to the adzuna API + [DEBUG] Using KEY=smcud4y6elxx7u6q58ewwv8rq01hpi3f + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "invalid pattern", - input: fmt.Sprintf("adzuna %s", invalidPattern), - want: nil, + name: "valid pattern - only id", + input: ` + [INFO] Sending request to the adzuna API + [DEBUG] Using ID=cxu9w2g6 + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the adzuna API + [DEBUG] Using KEY=sxojb6ygb2wsx0o + [DEBUG] Using ID=cxu9w2g6 + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -57,22 +88,15 @@ func TestAdzuna_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -84,6 +108,7 @@ func TestAdzuna_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aeroworkflow/aeroworkflow_test.go b/pkg/detectors/aeroworkflow/aeroworkflow_test.go index 2d5dc1a08..b554172b9 100644 --- a/pkg/detectors/aeroworkflow/aeroworkflow_test.go +++ b/pkg/detectors/aeroworkflow/aeroworkflow_test.go @@ -2,21 +2,15 @@ package aeroworkflow import ( "context" - "fmt" - "strings" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "qscVgy!WdvG;^#O:*?TG/806445634" - invalidPattern = "qscVg&!WdvG;^#O:*?TG/8064456A4" -) - func TestAeroWorkflow_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -27,29 +21,66 @@ func TestAeroWorkflow_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("aeroworkflow = '%s'", validPattern), - want: []string{"qscVgy!WdvG;^#O:*?TG806445634"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the aeroworkflow API + [DEBUG] Using aeroworkflow KEY=VmFYK7WG3CkgVmTl:c*X + [DEBUG] Using aeroworkflow ID=678436 + [INFO] Response received: 200 OK + `, + want: []string{"VmFYK7WG3CkgVmTl:c*X678436"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("aeroworkflow keyword is not close to the real id and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {aeroworkflow 6} + {aeroworkflow AQAAABAAA XjPSUOhREIN:4HX2#akH} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"XjPSUOhREIN:4HX2#akH6"}, }, { - name: "valid pattern - only key", - input: fmt.Sprintf("aeroworkflow %s", strings.Split(validPattern, "/")[0]), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to the aeroworkflow API + [DEBUG] Using KEY=VmFYK7WG3CkgVmTl:c*X + [DEBUG] Using ID=678436 + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "valid pattern - only id", - input: fmt.Sprintf("aeroworkflow %s", strings.Split(validPattern, "/")[1]), - want: nil, + name: "valid pattern - only key", + input: ` + [INFO] Sending request to the aeroworkflow API + [DEBUG] Using KEY=VmFYK7WG3CkgVmTl:c*X + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "invalid pattern", - input: fmt.Sprintf("aeroworkflow %s", invalidPattern), - want: nil, + name: "valid pattern - only id", + input: ` + [INFO] Sending request to the aeroworkflow API + [DEBUG] Using ID=678436 + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the aeroworkflow API + [DEBUG] Using KEY=VmFYK7WG3CkgVmTl:c*X + [DEBUG] Using ID=cxu9w2g6 + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -57,22 +88,15 @@ func TestAeroWorkflow_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -84,6 +108,7 @@ func TestAeroWorkflow_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/agora/agora_test.go b/pkg/detectors/agora/agora_test.go index bf050034c..13e6aac8d 100644 --- a/pkg/detectors/agora/agora_test.go +++ b/pkg/detectors/agora/agora_test.go @@ -2,28 +2,15 @@ package agora import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validKeyPattern = "asdf0987mnbv1234qsxojb6ygb2wsx0o" - validSecretPattern = "beqr7215fr4g6bfjkmnvxrtygb2wsxap" - complexPattern = `agora credentials - these are some example credentials for login. - use these to login. - key: asdf0987mnbv1234qsxojb6ygb2wsx0o - secret: beqr7215fr4g6bfjkmnvxrtygb2wsxap - loginUrl: https://www.agora.com/example_login - ` - invalidPattern = "asdf0987mNbv1234qsxojb6ygb2w$x0o/beqr7215fr4g6bfjkmnVxrtygb2wsxap" -) - func TestAgora_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -34,34 +21,66 @@ func TestAgora_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("agora key='%s' - secret='%s'", validKeyPattern, validSecretPattern), - want: []string{validKeyPattern + validSecretPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the agora API + [DEBUG] Using Token=6p77f9gjhxx9mwdj86of7y7820bh49vw + [DEBUG] Using Secret=qi6txx6vd0qzn6j01xj9rr6clyejvjw5 + [INFO] Response received: 200 OK + `, + want: []string{"6p77f9gjhxx9mwdj86of7y7820bh49vwqi6txx6vd0qzn6j01xj9rr6clyejvjw5"}, }, { - name: "valid complex pattern", - input: fmt.Sprintf("agora data='%s'", complexPattern), - want: []string{validKeyPattern + validSecretPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {agora 3devtbiys8b282kidr9u78kjq8xdtlo1} + {AQAAABAAA bc7c6tag5jfuhz4y7v6v05dx2wq2z1ua} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"3devtbiys8b282kidr9u78kjq8xdtlo1bc7c6tag5jfuhz4y7v6v05dx2wq2z1ua"}, }, { - name: "valid pattern - out of prefix range", - input: fmt.Sprintf("agora keyword is not close to the real key or secret = '%s|%s'", validKeyPattern, validSecretPattern), - want: nil, + name: "valid pattern - out of prefix range", + input: ` + [INFO] Sending request to the agora API + [DEBUG] Using 6p77f9gjhxx9mwdj86of7y7820bh49vw + [DEBUG] Using qi6txx6vd0qzn6j01xj9rr6clyejvjw5 + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "valid pattern - only key", - input: fmt.Sprintf("agora key%s", validKeyPattern), - want: nil, + name: "valid pattern - only key", + input: ` + [INFO] Sending request to the agora API + [DEBUG] Using Key=6p77f9gjhxx9mwdj86of7y7820bh49vw + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "valid pattern - only secret", - input: fmt.Sprintf("agora secret%s", validSecretPattern), - want: nil, + name: "valid pattern - only secret", + input: ` + [INFO] Sending request to the agora API + [DEBUG] Using Secret=qi6txx6vd0qzn6j01xj9rr6clyejvjw5 + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "invalid pattern", - input: fmt.Sprintf("agora %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + [INFO] Sending request to the agora API + [DEBUG] Using KEY=qi6txx6vd0qzn6j01xj9rr6clyejvjw + [DEBUG] Using ID=qi6txx6vd0qzn6j01xj9rr6clyejvjw5yt + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -69,22 +88,15 @@ func TestAgora_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -96,6 +108,7 @@ func TestAgora_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aha/aha_test.go b/pkg/detectors/aha/aha_test.go index 9499a5ff9..baf5d2284 100644 --- a/pkg/detectors/aha/aha_test.go +++ b/pkg/detectors/aha/aha_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -29,6 +30,20 @@ func TestAha_Pattern(t *testing.T) { `, want: []string{"81a1411a7e276fd88819df3137eb406e0f281f8a8c417947ca4b025890c8541cexample.aha.io"}, }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {aha 3af0b286b668d9636fd68076d6c87a333fe285fd41593cfceab36b35606c915a} + {AQAAABAAA ACTp3nufSEO791nIReS5udnRVFcG9j6-CqBJogBxo1pbql.aha.io} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"3af0b286b668d9636fd68076d6c87a333fe285fd41593cfceab36b35606c915aACTp3nufSEO791nIReS5udnRVFcG9j6-CqBJogBxo1pbql.aha.io"}, + }, { name: "valid pattern - key out of prefix range", input: ` @@ -73,22 +88,15 @@ func TestAha_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestAha_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/airbrakeprojectkey/airbrakeprojectkey_test.go b/pkg/detectors/airbrakeprojectkey/airbrakeprojectkey_test.go index 7c70bb9c3..3122824a8 100644 --- a/pkg/detectors/airbrakeprojectkey/airbrakeprojectkey_test.go +++ b/pkg/detectors/airbrakeprojectkey/airbrakeprojectkey_test.go @@ -2,21 +2,15 @@ package airbrakeprojectkey import ( "context" - "fmt" - "strings" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "qwmnerBv56zxpocvkjqr78afvYUx90Op/451298" - invalidPattern = "qwmnerBv56zxpocvkjqr78afvYU$90Op/4512987" -) - func TestAirBrakeProjectKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -27,29 +21,67 @@ func TestAirBrakeProjectKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("airbrake = '%s'", validPattern), - want: []string{"qwmnerBv56zxpocvkjqr78afvYUx90Op451298"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the airbrake API + [DEBUG] Using airbrake Key=7B759RwRR5Txo9pDxXtPNcrTOj0zhvmR + [DEBUG] Using airbrake ID=856019 + [INFO] Response received: 200 OK + `, + want: []string{"7B759RwRR5Txo9pDxXtPNcrTOj0zhvmR856019"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("airbrake keyword is not close to the real key and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {airbrake 691149} + {airbrake AQAAABAAA hYNK8PlcGXZ6PXXDFJI89LCjpoM8koTx} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"hYNK8PlcGXZ6PXXDFJI89LCjpoM8koTx691149"}, }, { - name: "valid pattern - only key", - input: fmt.Sprintf("airbrake %s", strings.Split(validPattern, "/")[0]), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [INFO] airbrake API request handling + [INFO] Sending request to the API + [DEBUG] Using Key=7B759RwRR5Txo9pDxXtPNcrTOj0zhvmR + [DEBUG] Using ID=856019 + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "valid pattern - only ID", - input: fmt.Sprintf("airbrake %s", strings.Split(validPattern, "/")[0]), - want: nil, + name: "valid pattern - only key", + input: ` + [INFO] Sending request to the airbrake API + [DEBUG] Using airbrake Key=7B759RwRR5Txo9pDxXtPNcrTOj0zhvmR + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "invalid pattern", - input: fmt.Sprintf("airbrake = '%s'", invalidPattern), - want: nil, + name: "valid pattern - only ID", + input: ` + [INFO] Sending request to the airbrake API + [DEBUG] Using airbrake ID=856019 + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the airbrake API + [DEBUG] Using airbrake Key=qwmnerBv56zx**cvkjqr78afvYU$90Op + [DEBUG] Using airbrake ID=856019 + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -57,22 +89,15 @@ func TestAirBrakeProjectKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -84,6 +109,7 @@ func TestAirBrakeProjectKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/airbrakeuserkey/airbrakeuserkey_test.go b/pkg/detectors/airbrakeuserkey/airbrakeuserkey_test.go index b41696885..6c3833987 100644 --- a/pkg/detectors/airbrakeuserkey/airbrakeuserkey_test.go +++ b/pkg/detectors/airbrakeuserkey/airbrakeuserkey_test.go @@ -2,20 +2,15 @@ package airbrakeuserkey import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "qsCGuilpkk2ngrsz75wtYqsCGuilpkk2ngrsz75w" - invalidPattern = "Qs%CGuil#pkk2ngrsz75wtYqsCGuilpkk2ngrsz75w" -) - func TestAirBrakeUserKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAirBrakeUserKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("airbrake = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the airbrake API + [DEBUG] Using Key=qsCGuilpkk2ngrsz75wtYqsCGuilpkk2ngrsz75w + [INFO] Response received: 200 OK + `, + want: []string{"qsCGuilpkk2ngrsz75wtYqsCGuilpkk2ngrsz75w"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("airbrake keyword is not close to the real key and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {airbrake 691149} + {airbrake AQAAABAAA UTDwMhGhuk0T04V0yqTqcKIwSSp7syUyQRG8JwoF} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"UTDwMhGhuk0T04V0yqTqcKIwSSp7syUyQRG8JwoF"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("airbrake = '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] airbrake api processing + [INFO] Sending request to the API + [DEBUG] Using Key=qsCGuilpkk2ngrsz75wtYqsCGuilpkk2ngrsz75w + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the airbrake API + [DEBUG] Using airbrake Key=Qs%CGuil#pkk2ngrsz75wtYqsCGuilpkk2ngrsz75w + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAirBrakeUserKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAirBrakeUserKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/airship/airship_test.go b/pkg/detectors/airship/airship_test.go index dc354533b..a3923ce9c 100644 --- a/pkg/detectors/airship/airship_test.go +++ b/pkg/detectors/airship/airship_test.go @@ -2,20 +2,15 @@ package airship import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "123abcdef456ghijkl789mnopqr012stuvwx3455123abcdef456ghijkl789mnopqr012stuvwx3455trdfrq95acr" - invalidPattern = "123#abcdef456gh$ijkl789mnopqr012stuvwX3455123abcdef456ghijkl789mnopqr012stuvwx3455trdfrq" -) - func TestAirship_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAirship_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("airship = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the airship API + [DEBUG] Using Key=O3BV99CUDw3xYUAL0tHGYUe7mOj5PA5vTnLdJwULCTh9dxk9PmmTpL1kI846G3QGIsECVyVSsxZnIbfSwWc8xuX843W + [INFO] Response received: 200 OK + `, + want: []string{"O3BV99CUDw3xYUAL0tHGYUe7mOj5PA5vTnLdJwULCTh9dxk9PmmTpL1kI846G3QGIsECVyVSsxZnIbfSwWc8xuX843W"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("airship keyword is not close to the real key and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {airship} + {airship AQAAABAAA oVH3yIO1oAoXpK9Rc01EGNNTuw6d4Zyt07YNFmje644Ht00hvAaYwldNOV9vIPQw6dYHJLRgp2f75YdJ9OiICkYVhMI} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"oVH3yIO1oAoXpK9Rc01EGNNTuw6d4Zyt07YNFmje644Ht00hvAaYwldNOV9vIPQw6dYHJLRgp2f75YdJ9OiICkYVhMI"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("airship = '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] airship api processing + [INFO] Sending request to the API + [DEBUG] Using Key=O3BV99CUDw3xYUAL0tHGYUe7mOj5PA5vTnLdJwULCTh9dxk9PmmTpL1kI846G3QGIsECVyVSsxZnIbfSwWc8xuX843W + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the airship API + [DEBUG] Using Key=O3BV99CUDw3xY#AL0tHGYUe7mOj5PA5vTnLdJwULCTh9dxk9PmmTpL1kI846G3QGIsECVyVSsxZnIbfSwWc8xuX843W + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAirship_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAirship_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/airtableoauth/airtableoauth_test.go b/pkg/detectors/airtableoauth/airtableoauth_test.go index f2d17e371..dbef0684b 100644 --- a/pkg/detectors/airtableoauth/airtableoauth_test.go +++ b/pkg/detectors/airtableoauth/airtableoauth_test.go @@ -2,21 +2,15 @@ package airtableoauth import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern1 = "oaajtCy2lVMUN1Cm5.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsImV4cGlyZXNBdCI6IjIwMjUtMDItMDNUMTk6NTY6MzcuMDAwWiIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwic2VjcmV0IjoiMzczNThlNzdlZjlhMjljY2Q5MWIwNmNlNTdkZDYxNDg0MWVmNmIyOWYwYjQ5ZWE0MTMxZGI4NzBkNTAzYTE1NyJ9.0d67c8b334048135a93615610445e4aa90c6af6222392b49eea9419e1d6717d0" - validPattern2 = "oaaRYiYSlTFXZzxDM.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwiZXhwaXJlc0F0IjoiMjAyNS0wMS0yOVQwMDowMTo0NC4wMDBaIiwic2VjcmV0IjoiZjYyOWE1MWVkM2M0ZjU5ODlmOTcyMDU1ZjkwODk3NDA4NmU0NjQxY2JhODU5Y2FhZTJkZjliMWQwODg0ZjIzMiJ9.27a8998029ac9bdd599b435572821dcb63c60cbf62b9cb2ba2a73511e5553d66" - invalidPattern = "oaaRYiYSlTFXZzxDM.v2.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwiZXhwaXJlc0F0IjoiMjAyNS0wMS0yOVQwMDowMTo0NC4wMDBaIiwic2VjcmV0IjoiZjYyOWE1MWVkM2M0ZjU5ODlmOTcyMDU1ZjkwODk3NDA4NmU0NjQxY2JhODU5Y2FhZTJkZjliMWQwODg0ZjIzMiJ9.27a8998029ac9bdd599b435572821dcb63c60cbf62b9cb2ba2a73511e5553d66" -) - func TestAirtableoauth_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,20 +20,50 @@ func TestAirtableoauth_Pattern(t *testing.T) { want []string }{ { - name: "typical pattern", - input: fmt.Sprintf("airtable token = '%s'", validPattern1), - want: []string{validPattern1}, + name: "valid pattern", + input: ` + [INFO] Sending request to the airtable API + [DEBUG] Using Key=oaajtCy2lVMUN1Cm5.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsImV4cGlyZXNBdCI6IjIwMjUtMDItMDNUMTk6NTY6MzcuMDAwWiIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwic2VjcmV0IjoiMzczNThlNzdlZjlhMjljY2Q5MWIwNmNlNTdkZDYxNDg0MWVmNmIyOWYwYjQ5ZWE0MTMxZGI4NzBkNTAzYTE1NyJ9.0d67c8b334048135a93615610445e4aa90c6af6222392b49eea9419e1d6717d0 + [INFO] Response received: 200 OK + `, + want: []string{"oaajtCy2lVMUN1Cm5.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsImV4cGlyZXNBdCI6IjIwMjUtMDItMDNUMTk6NTY6MzcuMDAwWiIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwic2VjcmV0IjoiMzczNThlNzdlZjlhMjljY2Q5MWIwNmNlNTdkZDYxNDg0MWVmNmIyOWYwYjQ5ZWE0MTMxZGI4NzBkNTAzYTE1NyJ9.0d67c8b334048135a93615610445e4aa90c6af6222392b49eea9419e1d6717d0"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {airtable} + {airtable AQAAABAAA iKMJv6D1mmUvunFTZLfm4RrYhdrt5JCBMv.v1.r8IBnGw7b_vW0fl0MDJqPRUEsDdHtNYW9ANwPFm40V_M4knoEaulKL-5lmtWoRq9fjG-GORe8efob5e658nTiOkdYC.8a8d3} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"iKMJv6D1mmUvunFTZLfm4RrYhdrt5JCBMv.v1.r8IBnGw7b_vW0fl0MDJqPRUEsDdHtNYW9ANwPFm40V_M4knoEaulKL-5lmtWoRq9fjG-GORe8efob5e658nTiOkdYC.8a8d3"}, }, { name: "finds all matches", - input: fmt.Sprintf(`airtable token 1 = '%s' - airtabl token 2 = '%s'`, validPattern1, validPattern2), - want: []string{validPattern1, validPattern2}, + input: ` + [INFO] Sending request to the airtable API + [DEBUG] Using Key=oaajtCy2lVMUN1Cm5.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsImV4cGlyZXNBdCI6IjIwMjUtMDItMDNUMTk6NTY6MzcuMDAwWiIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwic2VjcmV0IjoiMzczNThlNzdlZjlhMjljY2Q5MWIwNmNlNTdkZDYxNDg0MWVmNmIyOWYwYjQ5ZWE0MTMxZGI4NzBkNTAzYTE1NyJ9.0d67c8b334048135a93615610445e4aa90c6af6222392b49eea9419e1d6717d0 + [ERROR] Response received: 401 UnAuthorized + [DEBUG] Using Key=oaaRYiYSlTFXZzxDM.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwiZXhwaXJlc0F0IjoiMjAyNS0wMS0yOVQwMDowMTo0NC4wMDBaIiwic2VjcmV0IjoiZjYyOWE1MWVkM2M0ZjU5ODlmOTcyMDU1ZjkwODk3NDA4NmU0NjQxY2JhODU5Y2FhZTJkZjliMWQwODg0ZjIzMiJ9.27a8998029ac9bdd599b435572821dcb63c60cbf62b9cb2ba2a73511e5553d66 + [INFO] Response received: 200 OK + `, + want: []string{ + "oaajtCy2lVMUN1Cm5.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsImV4cGlyZXNBdCI6IjIwMjUtMDItMDNUMTk6NTY6MzcuMDAwWiIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwic2VjcmV0IjoiMzczNThlNzdlZjlhMjljY2Q5MWIwNmNlNTdkZDYxNDg0MWVmNmIyOWYwYjQ5ZWE0MTMxZGI4NzBkNTAzYTE1NyJ9.0d67c8b334048135a93615610445e4aa90c6af6222392b49eea9419e1d6717d0", + "oaaRYiYSlTFXZzxDM.v1.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwiZXhwaXJlc0F0IjoiMjAyNS0wMS0yOVQwMDowMTo0NC4wMDBaIiwic2VjcmV0IjoiZjYyOWE1MWVkM2M0ZjU5ODlmOTcyMDU1ZjkwODk3NDA4NmU0NjQxY2JhODU5Y2FhZTJkZjliMWQwODg0ZjIzMiJ9.27a8998029ac9bdd599b435572821dcb63c60cbf62b9cb2ba2a73511e5553d66", + }, }, { - name: "invalid pattern", - input: fmt.Sprintf("airtable token = '%s'", invalidPattern), - want: []string{}, + name: "invalid pattern", + input: ` + [INFO] Sending request to the airtable API + [DEBUG] Using Key=oaaRYiYSlTFXZzxDM.v2.eyJ1c2VySWQiOiJ1c3JjQ09QVlJudGlrU1lzdyIsIm9hdXRoQXBwbGljYXRpb25JZCI6Im9hcG14aXcyUlRrVGlzcHJIIiwiZXhwaXJlc0F0IjoiMjAyNS0wMS0yOVQwMDowMTo0NC4wMDBaIiwic2VjcmV0IjoiZjYyOWE1MWVkM2M0ZjU5ODlmOTcyMDU1ZjkwODk3NDA4NmU0NjQxY2JhODU5Y2FhZTJkZjliMWQwODg0ZjIzMiJ9.27a8998029ac9bdd599b435572821dcb63c60cbf62b9cb2ba2a73511e5553d66 + [ERROR] Response received: 401 UnAuthorized + `, + want: []string{}, }, } @@ -47,22 +71,15 @@ func TestAirtableoauth_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -74,6 +91,7 @@ func TestAirtableoauth_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/airtablepersonalaccesstoken/airtablepersonalaccesstoken_test.go b/pkg/detectors/airtablepersonalaccesstoken/airtablepersonalaccesstoken_test.go index 2e602eaff..9a6138f90 100644 --- a/pkg/detectors/airtablepersonalaccesstoken/airtablepersonalaccesstoken_test.go +++ b/pkg/detectors/airtablepersonalaccesstoken/airtablepersonalaccesstoken_test.go @@ -2,21 +2,15 @@ package airtablepersonalaccesstoken import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern1 = "patfqpIZBPU6EAt5x.458546d9c77b21f8a98141f2a4039d5626010f19efc16c20d57c4f41d44c8c85" - validPattern2 = "pat0VXr5I2HcapZE8.da2606afb7d97e936719ec952a4a18b44045e385d4ddf4f38dcc246fb63f0165" - invalidPattern = "tokfqpIZBPU6EAt5x.458546d9c77b21f8a98141f2a403-d5626010f19efc16c20d57c4f41d44c8c85" -) - func TestAirtablepersonalaccesstoken_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,20 +20,50 @@ func TestAirtablepersonalaccesstoken_Pattern(t *testing.T) { want []string }{ { - name: "typical pattern", - input: fmt.Sprintf("airtable token = '%s'", validPattern1), - want: []string{validPattern1}, + name: "valid pattern", + input: ` + [INFO] Sending request to the airtable API + [DEBUG] Using Key=patfqpIZBPU6EAt5x.458546d9c77b21f8a98141f2a4039d5626010f19efc16c20d57c4f41d44c8c85 + [INFO] Response received: 200 OK + `, + want: []string{"patfqpIZBPU6EAt5x.458546d9c77b21f8a98141f2a4039d5626010f19efc16c20d57c4f41d44c8c85"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {airtable} + {airtable AQAAABAAA pat2kATFGrujqJTbT.e2082656c470902d83b47dc804e693df1deb30161affbda39d879a2cf44bef13} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"pat2kATFGrujqJTbT.e2082656c470902d83b47dc804e693df1deb30161affbda39d879a2cf44bef13"}, }, { name: "finds all matches", - input: fmt.Sprintf(`airtable token 1 = '%s' - airtable token 2 = '%s'`, validPattern1, validPattern2), - want: []string{validPattern1, validPattern2}, + input: ` + [INFO] Sending request to the API + [DEBUG] Using airtable Key=patfqpIZBPU6EAt5x.458546d9c77b21f8a98141f2a4039d5626010f19efc16c20d57c4f41d44c8c85 + [ERROR] Response received: 401 UnAuthorized + [DEBUG] Using airtable Key=pat0VXr5I2HcapZE8.da2606afb7d97e936719ec952a4a18b44045e385d4ddf4f38dcc246fb63f0165 + [INFO] Response received: 200 OK + `, + want: []string{ + "patfqpIZBPU6EAt5x.458546d9c77b21f8a98141f2a4039d5626010f19efc16c20d57c4f41d44c8c85", + "pat0VXr5I2HcapZE8.da2606afb7d97e936719ec952a4a18b44045e385d4ddf4f38dcc246fb63f0165", + }, }, { - name: "invalid pattern", - input: fmt.Sprintf("airtable token = '%s'", invalidPattern), - want: []string{}, + name: "invalid pattern", + input: ` + [INFO] Sending request to the airtable API + [DEBUG] Using Key=patfqpIZBPU6EAt5xe.458546d9c77b21f8a98141f2a403-d5626010f19efc16c20d57c4f41d44c8c85 + [ERROR] Response received: 401 UnAuthorized + `, + want: []string{}, }, } @@ -47,22 +71,15 @@ func TestAirtablepersonalaccesstoken_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -74,6 +91,7 @@ func TestAirtablepersonalaccesstoken_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/airvisual/airvisual_test.go b/pkg/detectors/airvisual/airvisual_test.go index b4d585384..e3ff37e97 100644 --- a/pkg/detectors/airvisual/airvisual_test.go +++ b/pkg/detectors/airvisual/airvisual_test.go @@ -2,20 +2,15 @@ package airvisual import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "qscgyygcsq-wdvvok7slklklaasnd8afafxd" - invalidPattern = "wdvvok7slklklaasnd8afafxd" -) - func TestAirVisual_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAirVisual_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("airvisual = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the airvisual API + [DEBUG] Using Key=qscgyygcsq-wdvvok7slklklaasnd8afafxd + [INFO] Response received: 200 OK + `, + want: []string{"qscgyygcsq-wdvvok7slklklaasnd8afafxd"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("airvisual keyword is not close to the real key and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {airvisual} + {airvisual AQAAABAAA rtcbsxiee3d5au8ik14g-8iqrsu8thl1pku8} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"rtcbsxiee3d5au8ik14g-8iqrsu8thl1pku8"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("airvisual key: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] airvisual api processing + [INFO] Sending request to the API + [DEBUG] Using Key=qscgyygcsq-wdvvok7slklklaasnd8afafxd + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the airvisual API + [DEBUG] Using Key=wdvvok7slklklaasnd8afafxd + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAirVisual_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAirVisual_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aiven/aiven_test.go b/pkg/detectors/aiven/aiven_test.go index f6447a02f..d7087d0b7 100644 --- a/pkg/detectors/aiven/aiven_test.go +++ b/pkg/detectors/aiven/aiven_test.go @@ -2,20 +2,15 @@ package aiven import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = `ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef123/+==ABCdef12` - invalidPattern = `ABCdef123` -) - func TestAiven_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAiven_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("aiven = '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the aiven API + [DEBUG] Using Key = yb+Ygm82FfUworm2exB+Uk255p0uQKmmfx4ut1KfsZ3YI3Gp2xPYyxZgrwYabMxXXO4WPsK7xlLJRy0BWIpM2SKnzA2p69P8aOmYbl24ZiVGlLXyQxeVDDy7gru5Yzt=Y1UDLBpsW=hhGIKsrPgc/7hpxuEfEqbXJe5IBYO484F+ekaTmYN4nTF94O==3WuG+WuSW7zaYzXH1V==kZFj07zBtmShS0z/lW=N3HipH=oJjXI2pyFxU+A7vM9yHdUHoiZEOVoWsyp5zO1ajBOqFr=3jIIaXWmbH33dP2ZNQFJhqbeg6JlXA9GpfMFht5=ZCC1IirWCNp=UILbmZtvu9d2M8U0YNHwAGKtjrPS5lZvAU+W5s2Ti + [INFO] Response received: 200 OK + `, + want: []string{"yb+Ygm82FfUworm2exB+Uk255p0uQKmmfx4ut1KfsZ3YI3Gp2xPYyxZgrwYabMxXXO4WPsK7xlLJRy0BWIpM2SKnzA2p69P8aOmYbl24ZiVGlLXyQxeVDDy7gru5Yzt=Y1UDLBpsW=hhGIKsrPgc/7hpxuEfEqbXJe5IBYO484F+ekaTmYN4nTF94O==3WuG+WuSW7zaYzXH1V==kZFj07zBtmShS0z/lW=N3HipH=oJjXI2pyFxU+A7vM9yHdUHoiZEOVoWsyp5zO1ajBOqFr=3jIIaXWmbH33dP2ZNQFJhqbeg6JlXA9GpfMFht5=ZCC1IirWCNp=UILbmZtvu9d2M8U0YNHwAGKtjrPS5lZvAU+W5s2Ti"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("aiven keyword is not close to the real key and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {aiven} + {aiven AQAAABAAA IGhXNR6g7rogABp/H2iDQu7TgkXpvn9KnwzJfeh+8p7M=JVsI2QoQ38mmQHt450bQC4wBOGFhV+9QT2KGWSMfTOxTUrUXygaLlwsXo/RBxKXyOdh=/L8EGGrqG6=qbd0UzDAfc0xeAfXd30RGj+Ypsrrvdda=ZPa32BBID5r2ClfJSbgpfWIpVC1b5vlqCdy5LIWABZJzjBC5VweqZ04XFaCh+15NuSQ4E0KdGwPdkrfxxjY20I1wDvlKxzxL7dfCly3KVlQv7KBEFSLaLRNRocPYToUXqU4yAXKvXf03K=k1mahpxFUp94c35k/n055LVs=xbyL6AKdW=sCCa1AFIYKBDMBprTsZ6Al7DHx=XA6qLNWYxS7} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"IGhXNR6g7rogABp/H2iDQu7TgkXpvn9KnwzJfeh+8p7M=JVsI2QoQ38mmQHt450bQC4wBOGFhV+9QT2KGWSMfTOxTUrUXygaLlwsXo/RBxKXyOdh=/L8EGGrqG6=qbd0UzDAfc0xeAfXd30RGj+Ypsrrvdda=ZPa32BBID5r2ClfJSbgpfWIpVC1b5vlqCdy5LIWABZJzjBC5VweqZ04XFaCh+15NuSQ4E0KdGwPdkrfxxjY20I1wDvlKxzxL7dfCly3KVlQv7KBEFSLaLRNRocPYToUXqU4yAXKvXf03K=k1mahpxFUp94c35k/n055LVs=xbyL6AKdW=sCCa1AFIYKBDMBprTsZ6Al7DHx=XA6qLNWYxS7"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("aiven = '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] aiven api processing + [INFO] Sending request to the API + [DEBUG] Using Key=yb+Ygm82FfUworm2exB+Uk255p0uQKmmfx4ut1KfsZ3YI3Gp2xPYyxZgrwYabMxXXO4WPsK7xlLJRy0BWIpM2SKnzA2p69P8aOmYbl24ZiVGlLXyQxeVDDy7gru5Yzt=Y1UDLBpsW=hhGIKsrPgc/7hpxuEfEqbXJe5IBYO484F+ekaTmYN4nTF94O==3WuG+WuSW7zaYzXH1V==kZFj07zBtmShS0z/lW=N3HipH=oJjXI2pyFxU+A7vM9yHdUHoiZEOVoWsyp5zO1ajBOqFr=3jIIaXWmbH33dP2ZNQFJhqbeg6JlXA9GpfMFht5=ZCC1IirWCNp=UILbmZtvu9d2M8U0YNHwAGKtjrPS5lZvAU+W5s2Ti + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the aiven API + [DEBUG] Using Key=SSs8PGhwqWzb4qfqiwLV/bNHfiQ2VSKyX88AAYm3+CGHbTe/FYXRNOYYHO=PXwuL/GftiES7j8ffzWW9p1dAyNc6hZZpoazmd+Vf1kbukZSL8QO/LdKFI/YFlupu0dELqQVHeZi/cJlnp6aQeY7zIJiHhJS51ZVdOamc=zOUMebry3BYOo2LhYIz+mLND7s5/cHZZpkEvTXrKnVf4vdYMl+fawv84AYCTo9pry8FQBsqRex2HL98kAiqhVYG+nLyRz/hZCo8owaRkzli1BUT4O63TSKJIgnECOBvyZz7o+yX92BhDe+B2Tllk3y2=qG5TiEl2sCJI8V5GJ1cz52RpXx2hVXMi=1Zl5CHpX8Adr9VMbj$Co + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAiven_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAiven_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/alchemy/alchemy.go b/pkg/detectors/alchemy/alchemy.go index 3c2291ec2..700e08321 100644 --- a/pkg/detectors/alchemy/alchemy.go +++ b/pkg/detectors/alchemy/alchemy.go @@ -29,7 +29,7 @@ var ( // Keywords are used for efficiently pre-filtering chunks. // Use identifiers in the secret preferably, or the provider name. func (s Scanner) Keywords() []string { - return []string{"alchemy","alcht_"} + return []string{"alchemy", "alcht_"} } // FromData will find and optionally verify Alchemy secrets in a given set of bytes. diff --git a/pkg/detectors/alchemy/alchemy_test.go b/pkg/detectors/alchemy/alchemy_test.go index 38a7ba726..6473aebcf 100644 --- a/pkg/detectors/alchemy/alchemy_test.go +++ b/pkg/detectors/alchemy/alchemy_test.go @@ -2,10 +2,13 @@ package alchemy import ( "context" + "testing" + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" - "testing" ) func TestAlchemy_Pattern(t *testing.T) { @@ -17,20 +20,47 @@ func TestAlchemy_Pattern(t *testing.T) { want []string }{ { - name: "typical pattern", - input: "alchemy_token = '3aBcDFE5678901234567890_1a2b3c4d'", - want: []string{"3aBcDFE5678901234567890_1a2b3c4d"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the alchemy API + [DEBUG] Using Key=alcht_2Cy8xCLyvrAf7lZKfhQhyCr4RAID9D + [INFO] Response received: 200 OK + `, + want: []string{"alcht_2Cy8xCLyvrAf7lZKfhQhyCr4RAID9D"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {alchemy} + {alchemy AQAAABAAA 5iqW7gKQVXvwnykF9xAVfenemmnUJznI} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"5iqW7gKQVXvwnykF9xAVfenemmnUJznI"}, }, { name: "finds all matches", - input: `alchemy_token1 = '3aBcDFE5678901234567890_1a2b3c4d' -alchemy_token2 = '3aDcDFE56789012245678a0_1a2b3c2d'`, - want: []string{"3aBcDFE5678901234567890_1a2b3c4d", "3aDcDFE56789012245678a0_1a2b3c2d"}, + input: ` + [INFO] Sending request to the alchemy API + [DEBUG] Using Key=alcht_2Cy8xCLyvrAf7lZKfhQhyCr4RAID9D + [ERROR] Response received 401 UnAuthorized + [DEBUG] Using alchemy Key=xuQIeWFVEp8k8Uu9FwPx6X5C8IViOe1o + [INFO] Response received: 200 OK + `, + want: []string{"alcht_2Cy8xCLyvrAf7lZKfhQhyCr4RAID9D", "xuQIeWFVEp8k8Uu9FwPx6X5C8IViOe1o"}, }, { - name: "invalid pattern", - input: "alchemy_token = '1a2b3c4d'", - want: []string{}, + name: "invalid pattern", + input: ` + [INFO] Sending request to the alchemy API + [DEBUG] Using Key=alcht_a2Cy8xCLyvrAf7lZKfhQhyCr4RAID9D + [ERROR] Response received: 401 UnAuthorized + `, + want: []string{}, }, } @@ -38,22 +68,15 @@ alchemy_token2 = '3aDcDFE56789012245678a0_1a2b3c2d'`, t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -65,6 +88,7 @@ alchemy_token2 = '3aDcDFE56789012245678a0_1a2b3c2d'`, actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/alconost/alconost_test.go b/pkg/detectors/alconost/alconost_test.go index 0c4cc1f0e..f101775e5 100644 --- a/pkg/detectors/alconost/alconost_test.go +++ b/pkg/detectors/alconost/alconost_test.go @@ -2,20 +2,15 @@ package alconost import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "wdvnousa87acfxp9ioasrea4tbeasrfa" - invalidPattern = "wdvnousa87acfxp9ioasr$a4tBeasrfa" -) - func TestAlconost_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAlconost_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("alconost: '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the alconost API + [DEBUG] Using Key=wdvnousa87acfxp9ioasrea4tbeasrfa + [INFO] Response received: 200 OK + `, + want: []string{"wdvnousa87acfxp9ioasrea4tbeasrfa"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("alconost keyword is not close to the real key in the data = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {alconost} + {alconost AQAAABAAA Awxzhkwff46dtkt5pnvdlss6t2kA44a7} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"Awxzhkwff46dtkt5pnvdlss6t2kA44a7"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("alconost: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] alconost api processing + [INFO] Sending request to the API + [DEBUG] Using Key=wdvnousa87acfxp9ioasrea4tbeasrfa + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the alconost API + [DEBUG] Using Key=wdvnousa87acfxp9ioasra4tBeasrfa + [INFO] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAlconost_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAlconost_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/alegra/alegra_test.go b/pkg/detectors/alegra/alegra_test.go index 5594c9ba4..cf35bbda3 100644 --- a/pkg/detectors/alegra/alegra_test.go +++ b/pkg/detectors/alegra/alegra_test.go @@ -2,21 +2,15 @@ package alegra import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "wdvn-usa87a-fxp9ioas/testUser.1005@example.com" - validSpecialCharPattern = "wdvn-usa87a-fxp9ioas / test-User.1005@example.com" - invalidPattern = "wdvn-usa87a-fxp9ioasQQsstestUsQQ@example" -) - func TestAlegra_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -27,43 +21,65 @@ func TestAlegra_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("alegra: %s", validPattern), - want: []string{"wdvn-usa87a-fxp9ioas:wdvn-usa87a-fxp9ioas/testUser.1005@example.com"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using alegra Key=wdvn-usa87a-fxp9ioas + [DEBUG] Using alegra Email = testUser.1005@example.com + [INFO] Response received: 200 OK + `, + want: []string{"wdvn-usa87a-fxp9ioas:testUser.1005@example.com"}, }, { - name: "valid pattern - with special characters", - input: fmt.Sprintf("alegra: %s", validSpecialCharPattern), - want: []string{"wdvn-usa87a-fxp9ioas:test-User.1005@example.com"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {alegra kk18@example.com} + {alegra AQAAABAAA buihlmkfnh5m1lk5z6do} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"buihlmkfnh5m1lk5z6do:kk18@example.com"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("alegra keyword is not close to the real key and id = %s", validPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] alegra api processing + [INFO] Sending request to the API + [DEBUG] Using Key=wdvn-usa87a-fxp9ioas + [DEBUG] Using Email=testUser.1005@example.com + [INFO] Response received: 200 OK + `, + want: nil, }, { - name: "invalid pattern", - input: fmt.Sprintf("alegra: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using alegra Key=wdvn_usa87a-fxp9ioas + [DEBUG] Using alegra Email=testUser.1005@example.com + [INFO] Response received: 401 UnAuthorized + `, + want: nil, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) - if len(matchedDetectors) == 0 && test.want != nil { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + if len(matchedDetectors) == 0 { + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - t.Errorf("expected %d results, got %d", len(test.want), len(results)) + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +91,7 @@ func TestAlegra_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aletheiaapi/aletheiaapi_test.go b/pkg/detectors/aletheiaapi/aletheiaapi_test.go index e651d037f..46f99e433 100644 --- a/pkg/detectors/aletheiaapi/aletheiaapi_test.go +++ b/pkg/detectors/aletheiaapi/aletheiaapi_test.go @@ -2,20 +2,15 @@ package aletheiaapi import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "TEST01KEYPATTERN2024ALETHEIAAPIN" - invalidPattern = "TEST01kEYPATTERN2024ALETHEIAAPIN" -) - func TestAleTheIaAPI_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAleTheIaAPI_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("aletheiaapi: '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the aletheiaapi + [DEBUG] Using Key=LY027C40U2KNNZLFO1WEU3XQZ13LW515 + [INFO] Response received: 200 OK + `, + want: []string{"LY027C40U2KNNZLFO1WEU3XQZ13LW515"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("aletheiaapi keyword is not close to the real key and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {aletheiaapi} + {aletheiaapi AQAAABAAA K7SOW2B8QH9QE435NLH07PH22XL4YOPG} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"K7SOW2B8QH9QE435NLH07PH22XL4YOPG"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("aletheiaapi: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] aletheiaapi api processing + [INFO] Sending request to the API + [DEBUG] Using Key=LY027C40U2KNNZLFO1WEU3XQZ13LW515 + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the aletheiaapi + [DEBUG] Using Key=LY027c40U2KNNZLFO1WEU3XQZ13LW515 + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAleTheIaAPI_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAleTheIaAPI_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/algoliaadminkey/algoliaadminkey_test.go b/pkg/detectors/algoliaadminkey/algoliaadminkey_test.go index 5cdf314c0..e3dd01411 100644 --- a/pkg/detectors/algoliaadminkey/algoliaadminkey_test.go +++ b/pkg/detectors/algoliaadminkey/algoliaadminkey_test.go @@ -2,20 +2,15 @@ package algoliaadminkey import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "AlgoliaAdminKey010TESTINGPlmiOPC/ADMIN01KEY" - invalidPattern = "AlgoliaAdminN$TKey010TESTINGPlmiOPC/NonAdmin01ID" -) - func TestAlgoliaAdminKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,48 @@ func TestAlgoliaAdminKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("algolia: '%s'", validPattern), - want: []string{"ADMIN01KEY:AlgoliaAdminKey010TESTINGPlmiOPC"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using algolia Key=BsDaN7ZU7kFiUX5CpN8CUf3nkMaSeZYn + [DEBUG] Using docsearch ID=844XQV5SUA + [INFO] Response received: 200 OK + `, + want: []string{"844XQV5SUA:BsDaN7ZU7kFiUX5CpN8CUf3nkMaSeZYn"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("algolia keyword is not close to the real key and secret = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {appId 0VJ9I1WV78} + {algolia AQAAABAAA 4AYm3wz7nfnX7Bqtw5e5Qo3Z5vfBe0eS} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"0VJ9I1WV78:4AYm3wz7nfnX7Bqtw5e5Qo3Z5vfBe0eS"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("algolia: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [INFO] Sending request to the algolia API + [DEBUG] Using Key=BsDaN7ZU7kFiUX5CpN8CUf3nkMaSeZYn + [DEBUG] Using ID=844XQV5SUA + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using algolia Key=BsD-N7ZU7kFiUX5CpN8CUf3nkMaSeZYn + [DEBUG] Using docsearch ID=844XqV5SUA + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +70,15 @@ func TestAlgoliaAdminKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +90,7 @@ func TestAlgoliaAdminKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/alibaba/alibaba_test.go b/pkg/detectors/alibaba/alibaba_test.go index 8edb6f4cc..016bf20d5 100644 --- a/pkg/detectors/alibaba/alibaba_test.go +++ b/pkg/detectors/alibaba/alibaba_test.go @@ -2,20 +2,15 @@ package alibaba import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "abcDEF123ghiJKL456mnoPQR789std/LTAI123ABCdef456ghijkLMN" - invalidPattern = "abcDEF123ghiJKL456m$oPQR789/123ABCdef456ghijkLMN;" -) - func TestAliBaba_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,48 @@ func TestAliBaba_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("LTAI: '%s'", validPattern), - want: []string{"abcDEF123ghiJKL456mnoPQR789stdLTAI123ABCdef456ghijkLMN"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using Key=CwgR2UwgaWd7hgUdQkwFnK9vvEeO4R + [DEBUG] Using ID=LTAIXgRPqwF1DhBf6Q1uZ5DrM + [INFO] Response received: 200 OK + `, + want: []string{"CwgR2UwgaWd7hgUdQkwFnK9vvEeO4RLTAIXgRPqwF1DhBf6Q1uZ5DrM"}, }, { - name: "valid pattern - ignore special characters at end", - input: fmt.Sprintf("LTAI: '%s\"''", validPattern), - want: []string{"abcDEF123ghiJKL456mnoPQR789stdLTAI123ABCdef456ghijkLMN"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {WX6OtM8pbcrXWMIGc5evYousFWBlBm} + {AQAAABAAA LTAImg3ZeAPatbAtEDS9HVZ} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"WX6OtM8pbcrXWMIGc5evYousFWBlBmLTAImg3ZeAPatbAtEDS9HVZ"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("LTAI: '%s'", invalidPattern), - want: nil, + name: "valid pattern - ignore special characters at end", + input: ` + [INFO] Sending request to the API + [DEBUG] Using Key=CwgR2UwgaWd7hgUdQkwFnK9vvEeO4R + [DEBUG] Using ID=LTAIXgRPqwF1DhBf6Q1uZ5DrM; + [INFO] Response received: 200 OK + `, + want: []string{"CwgR2UwgaWd7hgUdQkwFnK9vvEeO4RLTAIXgRPqwF1DhBf6Q1uZ5DrM"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using Key=CwgR2UwgaWd7hgUdQkwFnK9vvEeO4 + [DEBUG] Using ID=LTAIXgRPqwF1DhBf6Q1uZ5DrMYPW + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +70,15 @@ func TestAliBaba_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +90,7 @@ func TestAliBaba_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/alienvault/alienvault_test.go b/pkg/detectors/alienvault/alienvault_test.go index 514c5de34..a14f84652 100644 --- a/pkg/detectors/alienvault/alienvault_test.go +++ b/pkg/detectors/alienvault/alienvault_test.go @@ -2,20 +2,15 @@ package alienvault import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "a3b9f8c1e2d4f5b6c7d8e9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0" - invalidPattern = "A$3b9f8c1e2d4f5b6c7d8e9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d" -) - func TestAlienVault_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAlienVault_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("alienvault: '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the alienvault API + [DEBUG] Using Key=3em7p52ec9ut4k9ccqha19rz3oyeqnij3mn3ivml577f8pb2179yz9totr648hmy + [INFO] Response received: 200 OK + `, + want: []string{"3em7p52ec9ut4k9ccqha19rz3oyeqnij3mn3ivml577f8pb2179yz9totr648hmy"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("alienvault keyword is not close to the real key in the data\n = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {alienvault} + {AQAAABAAA xyi7bj56t5b0hkinw4vz8qgffqhfb2ypemdnt407bke6s0ouuswvcdf5c1qpvse0} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"xyi7bj56t5b0hkinw4vz8qgffqhfb2ypemdnt407bke6s0ouuswvcdf5c1qpvse0"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("alienvault: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [INFO] Fetching data from alienvault + [INFO] Sending request to the API + [DEBUG] Using Key=3em7p52ec9ut4k9ccqha19rz3oyeqnij3mn3ivml577f8pb2179yz9totr648hmy + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the alienvault API + [DEBUG] Using Key=3em7p52ec9ut4k9ccqha19rz3o_eqnij3mn3ivml577f8pb2179yz9totr648hmy + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAlienVault_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAlienVault_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/allsports/allsports_test.go b/pkg/detectors/allsports/allsports_test.go index 81414fd8f..e16a5dbaf 100644 --- a/pkg/detectors/allsports/allsports_test.go +++ b/pkg/detectors/allsports/allsports_test.go @@ -2,20 +2,15 @@ package allsports import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "d1f2e3c4b5a6d7e8f9g0h1i2j3k4l5m6n7o8p9q0r1s2t3u4v5w6x7y8z9a0b1ce" - invalidPattern = "Ad1f2e3c4b5a6d7e8f9g0h1i2j3k4l5m6n7o8p9q0r1sRt3u4v5w6x7y8z9a0b1cE" -) - func TestAllSports_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAllSports_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("allsports: '%s'", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the allsports API + [DEBUG] Using Key=cq73u5azj3p3shfvzz3lw1typfqu6uduq7bophtq4veta7cnvd4s5htkb8lgk4vr + [INFO] Response received: 200 OK + `, + want: []string{"cq73u5azj3p3shfvzz3lw1typfqu6uduq7bophtq4veta7cnvd4s5htkb8lgk4vr"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("allsports keyword is not close to the real key in the data\n = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {allsports} + {AQAAABAAA bj8yzu3awie5akwiwcb7esqygqx14gt65j9lrcpec0v28ckkswtyza1x9747gap5} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"bj8yzu3awie5akwiwcb7esqygqx14gt65j9lrcpec0v28ckkswtyza1x9747gap5"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("allsports: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [DEBUG] allsports api processing + [INFO] Sending request to the API + [DEBUG] Using Key=cq73u5azj3p3shfvzz3lw1typfqu6uduq7bophtq4veta7cnvd4s5htkb8lgk4vr + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the allsports API + [DEBUG] Using Key=d1f2e3c4b5a6d7e8f9G0h1i2j3k4l5m6n7o8p9q0r1s2t3u4v5w6x7y8z9a0b1ce + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAllSports_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAllSports_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/amadeus/amadeus_test.go b/pkg/detectors/amadeus/amadeus_test.go index 5437f5f06..0c075b8a1 100644 --- a/pkg/detectors/amadeus/amadeus_test.go +++ b/pkg/detectors/amadeus/amadeus_test.go @@ -2,20 +2,15 @@ package amadeus import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6 / A1b2C3d4E5f6G7ho" - invalidPattern = "A1b2$3d4E5f6G7h8I9j(K1l2M3n4O5)6 / A1b2C3d4E^f6G7#8" -) - func TestAmadeus_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,48 @@ func TestAmadeus_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("amadeus: '%s'", validPattern), - want: []string{"A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6A1b2C3d4E5f6G7ho"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using amadeus Key=ttdveNai3Gj6Zrjvgz4fyBEWRLARCG6a + [DEBUG] Using amadeus Secret=9wqrSr2qveaqgQns + [INFO] Response received: 200 OK + `, + want: []string{"ttdveNai3Gj6Zrjvgz4fyBEWRLARCG6a9wqrSr2qveaqgQns"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("amadeus keyword is not close to the real key in the data\n = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {amadeus ey6U46qCx26dqzMVWAGiibt6m65mM5w9} + {amadeus AQAAABAAA Ew3TfmLHYaRjPnYO} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"ey6U46qCx26dqzMVWAGiibt6m65mM5w9Ew3TfmLHYaRjPnYO"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("amadeus: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [INFO] Sending request to the amadeus API + [DEBUG] Using Key=ttdveNai3Gj6Zrjvgz4fyBEWRLARCG6a + [DEBUG] Using Secret=9wqrSr2qveaqgQns + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the amadeus API + [DEBUG] Using amadeus Key=tthdveNai3Gj6Zrjvgz4fyBEWRLARCG6a + [DEBUG] Using amadeus Secret=9wqrSr2qveacqgQns + [INFO] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -46,22 +70,15 @@ func TestAmadeus_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +90,7 @@ func TestAmadeus_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/ambee/ambee_test.go b/pkg/detectors/ambee/ambee_test.go index 12dc72b45..42ad9e06d 100644 --- a/pkg/detectors/ambee/ambee_test.go +++ b/pkg/detectors/ambee/ambee_test.go @@ -2,20 +2,15 @@ package ambee import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4" - invalidPattern = "X3b4c5d6e7f8a9b0c1d2e3f4a5b6c7Z8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4" -) - func TestAmbee_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,19 +21,46 @@ func TestAmbee_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("ambee: '%s'", validPattern), - want: []string{"a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the ambee API + [DEBUG] Using Key=eccb41cc2d4dab96b748ed040e9b308161279820447ef4553ba6e6d20ecb9962 + [INFO] Response received: 200 OK + `, + want: []string{"eccb41cc2d4dab96b748ed040e9b308161279820447ef4553ba6e6d20ecb9962"}, }, { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("ambee keyword is not close to the real key in the data\n = '%s'", validPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {ambee} + {ambee AQAAABAAA b91280c63e1571ad928d52947cc31a14ad1bf5a83088d0346b94f6683cf22138} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"b91280c63e1571ad928d52947cc31a14ad1bf5a83088d0346b94f6683cf22138"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("ambee: '%s'", invalidPattern), - want: nil, + name: "valid pattern - key out of prefix range", + input: ` + [INFO] Fetching data from ambee + [INFO] Sending request to the API + [DEBUG] Using Key=eccb41cc2d4dab96b748ed040e9b308161279820447ef4553ba6e6d20ecb9962 + [INFO] Response received: 200 OK + `, + want: nil, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the ambee API + [DEBUG] Using Key=eccb41cc2d4dab96y748ed040e9b308161279820447ef4553ba6e6d20ecb9962 + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -46,22 +68,15 @@ func TestAmbee_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +88,7 @@ func TestAmbee_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/amplitudeapikey/amplitudeapikey_test.go b/pkg/detectors/amplitudeapikey/amplitudeapikey_test.go index e9fb9c351..e2060fe6e 100644 --- a/pkg/detectors/amplitudeapikey/amplitudeapikey_test.go +++ b/pkg/detectors/amplitudeapikey/amplitudeapikey_test.go @@ -2,26 +2,15 @@ package amplitudeapikey import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - amplitude key = 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d - amplitude secret = 5b3c4d5e5f7a8b9c0d1e2f2f3a4b4c6e - ` - invalidPattern = ` - amplitude key = 1a2b3c4d5e6f7a8g9c0d1e2f3a4b5c6d - amplitude secret = 5b3c4d5e5f7a8b9c0d1r2f2f3a4b4c6e - ` -) - func TestAmplitudeAPIKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -32,17 +21,44 @@ func TestAmplitudeAPIKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("amplitude: '%s'", validPattern), + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using amplitude Key=c2167730016af34b89e200ecf55710e8 + [DEBUG] Using amplitude Secret=5488620aa9073c09f1a16e2b1dc357b6 + [INFO] Response received: 200 OK + `, want: []string{ - "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d5b3c4d5e5f7a8b9c0d1e2f2f3a4b4c6e", - "5b3c4d5e5f7a8b9c0d1e2f2f3a4b4c6e1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d", + "c2167730016af34b89e200ecf55710e85488620aa9073c09f1a16e2b1dc357b6", + "5488620aa9073c09f1a16e2b1dc357b6c2167730016af34b89e200ecf55710e8", }, }, { - name: "invalid pattern", - input: fmt.Sprintf("amplitude: '%s'", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {amplitude aac639f65d80ec2eec96e775f598ce13} + {amplitude AQAAABAAA 8ac62041353622f9c5e4657807ff1eac} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{ + "aac639f65d80ec2eec96e775f598ce138ac62041353622f9c5e4657807ff1eac", + "8ac62041353622f9c5e4657807ff1eacaac639f65d80ec2eec96e775f598ce13", + }, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using amplitude Key=c2167730016rf34b89e200ecf55710e8 + [DEBUG] Using amplitude Secret=5488620aa9073q09f1a16e2b1dc357b6 + [INFO] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -50,22 +66,15 @@ func TestAmplitudeAPIKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -77,6 +86,7 @@ func TestAmplitudeAPIKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/anthropic/anthropic_test.go b/pkg/detectors/anthropic/anthropic_test.go index dd3515737..b4ea6730e 100644 --- a/pkg/detectors/anthropic/anthropic_test.go +++ b/pkg/detectors/anthropic/anthropic_test.go @@ -5,26 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - System Log - Authentication Token Issued - Date: 2025-02-04 14:32:10 UTC - Server: api-secure-03.internal - Service: Anthropic API Gateway - API Key: sk-ant-api03-abc123xyz-456def789ghij-klmnopqrstuvwx-3456yza789bcde-1234fghijklmnopby56aaaogaopaaaabc123xyzAA - Admin Key: sk-ant-admin01-abc12fake-456def789ghij-klmnopqrstuvwx-3456yza789bcde-12fakehijklmnopby56aaaogaopaaaabc123xyzAA - - Log Entry: - A new API and Admin key has been generated for service authentication. Please ensure that this key remains confidential and is not exposed in any public repositories or logs. - ` - invalidPattern = "sk-ant-api03-abc123xyz-456de-klMnopqrstuvwx-3456yza789bcde-1234fghijklmnopAA" -) - func TestAnthropic_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -35,17 +21,50 @@ func TestAnthropic_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, + name: "valid pattern", + input: ` + System Log - Authentication Token Issued + Date: 2025-02-04 14:32:10 UTC + Server: api-secure-03.internal + Service: Anthropic API Gateway + API Key: sk-ant-api03-abc123xyz-456def789ghij-klmnopqrstuvwx-3456yza789bcde-1234fghijklmnopby56aaaogaopaaaabc123xyzAA + Admin Key: sk-ant-admin01-abc12fake-456def789ghij-klmnopqrstuvwx-3456yza789bcde-12fakehijklmnopby56aaaogaopaaaabc123xyzAA + + Log Entry: + A new API and Admin key has been generated for service authentication. Please ensure that this key remains confidential and is not exposed in any public repositories or logs. + `, want: []string{ "sk-ant-api03-abc123xyz-456def789ghij-klmnopqrstuvwx-3456yza789bcde-1234fghijklmnopby56aaaogaopaaaabc123xyzAA", "sk-ant-admin01-abc12fake-456def789ghij-klmnopqrstuvwx-3456yza789bcde-12fakehijklmnopby56aaaogaopaaaabc123xyzAA", }, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {anthropic} + {AQAAABAAA sk-ant-api03-Dtjm9IZ_rYhS_ihHLZmPXhjJ6PN8UPp7vNO7qO3735RRDpf8xbWGinsch0McONXznUm-4KWoA7WU2otvvwHBR5QRjiLakAA} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"sk-ant-api03-Dtjm9IZ_rYhS_ihHLZmPXhjJ6PN8UPp7vNO7qO3735RRDpf8xbWGinsch0McONXznUm-4KWoA7WU2otvvwHBR5QRjiLakAA"}, + }, + { + name: "invalid pattern", + input: ` + System Log - Authentication Token Issued + Date: 2025-02-04 14:32:10 UTC + Server: api-secure-03.internal + Service: Anthropic API Gateway + API Key: sk-ant-api03-abc123xyz-456de-klMnopqrstuvwx-3456yza789bcde-1234fghijklmnopAA + + Log Entry: + A new API key has been generated for service authentication. Please ensure that this key remains confidential and is not exposed in any public repositories or logs. + `, + want: nil, }, } @@ -53,22 +72,15 @@ func TestAnthropic_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -80,6 +92,7 @@ func TestAnthropic_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/anypoint/anypoint_test.go b/pkg/detectors/anypoint/anypoint_test.go index 31f5a91df..95ecd6be1 100644 --- a/pkg/detectors/anypoint/anypoint_test.go +++ b/pkg/detectors/anypoint/anypoint_test.go @@ -2,41 +2,15 @@ package anypoint import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6 / org: abcd1234-ef56-gh78-ij90-klmn1234opqr" - complexPattern = ` - # Secret Configuration File - # Organization details - ORG_NAME=my_organization - ORG_ID=abcd1234-ef56-gh78-ij90-klmn1234opqr - - # Database credentials - DB_USERNAME=iamnotadmin - DB_PASSWORD=8f3b6d3e7c9a2f5e - - # OAuth tokens - ACCESS_TOKEN=abcxyz123 - REFRESH_TOKEN=zyxwvutsrqponmlkji9876543210abcd - - # API keys - API_KEY=sk-ant-api03-nothing-just-some-random-api-key-1234fghijklmnopAA - SECRET_KEY=1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6 - - # Endpoints - SERVICE_URL=https://api.example.com/v1/resource - ` - invalidPattern = "1a2b3C4d-5E6f-7g8H-9i0J-k1l2M3n4o5p6 / abcd1234-eF56-gH78-ij90-klmn1234opqr" -) - func TestAnypoint_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -47,19 +21,58 @@ func TestAnypoint_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("anypoint credentials: %s", validPattern), - want: []string{"1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6abcd1234-ef56-gh78-ij90-klmn1234opqr"}, + name: "valid pattern", + input: ` + # Anypoint Secret Configuration File + # Organization details + ORG_NAME=my_organization + ORG_ID=abcd1234-ef56-gh78-ij90-klmn1234opqr + + # OAuth tokens + ACCESS_TOKEN=abcxyz123 + REFRESH_TOKEN=zyxwvutsrqponmlkji9876543210abcd + + # API keys + SECRET_KEY=1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6 + + # Endpoints + SERVICE_URL=https://api.example.com/v1/resource + `, + want: []string{"1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6abcd1234-ef56-gh78-ij90-klmn1234opqr"}, }, { - name: "valid pattern - complex", - input: fmt.Sprintf("anypoint credentials: %s", complexPattern), - want: []string{"1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6abcd1234-ef56-gh78-ij90-klmn1234opqr"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {anypoint org rdogw4dd-6x3l-2nm3-jvl5-qi8dyheccgj7} + {AQAAABAAA 7jhlugw8-3tfb-7ju2-0i0y-7un6qxvknbvz} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"7jhlugw8-3tfb-7ju2-0i0y-7un6qxvknbvzrdogw4dd-6x3l-2nm3-jvl5-qi8dyheccgj7"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("anypoint credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + # Anypoint Secret Configuration File + # Organization details + ORG_NAME=my_organization + ORG_ID=abcd1234-ef56-gh78-ij90-klmn1234opqr + + # OAuth tokens + ACCESS_TOKEN=abcxyz123 + REFRESH_TOKEN=zyxwvutsrqponmlkji9876543210abcd + + # API keys + SECRET_KEY=1a2b3C4d-5E6f-7g8H-9i0J-k1l2M3n4o5p6 + + # Endpoints + SERVICE_URL=https://api.example.com/v1/resource + `, + want: nil, }, } @@ -67,22 +80,15 @@ func TestAnypoint_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -94,6 +100,7 @@ func TestAnypoint_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/anypointoauth2/anypointoauth2_test.go b/pkg/detectors/anypointoauth2/anypointoauth2_test.go index a2480abc9..1f2c4d433 100644 --- a/pkg/detectors/anypointoauth2/anypointoauth2_test.go +++ b/pkg/detectors/anypointoauth2/anypointoauth2_test.go @@ -2,41 +2,15 @@ package anypointoauth2 import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "anypoint id: e3cd10a87f53b2dfa4b5fd606e7d9eca / secret: ACE9d7E606Df5B4AFD2B35f78A01DC3E" - complexPattern = ` - # Secret Configuration File - # Organization details - ORG_NAME=my_organization - ORG_ID=abcd1234-ef56-gh78-ij90-klmn1234opqr - - # Database credentials - DB_USERNAME=iamnotadmin - DB_PASSWORD=8f3b6d3e7c9a2f5e - - # OAuth tokens - CLIENT_ID=e3cd10a87f53b2dfa4b5fd606e7d9eca - CLIENT_SECRET=ACE9d7E606Df5B4AFD2B35f78A01DC3E - - # API keys - API_KEY=sk-ant-api03-nothing-just-some-random-api-key-1234fghijklmnopAA - SECRET_KEY=1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6 - - # Endpoints - SERVICE_URL=https://api.example.com/v1/resource - ` - invalidPattern = "anypoint id: k4lzc5ty98tnfu3a11y8gnv5vb1281as / secret: 8SBT9p4NXPYVS89EPtYV29SVT2SFcD8A" -) - func TestAnypoint_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -47,19 +21,58 @@ func TestAnypoint_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("anypoint credentials: %s", validPattern), - want: []string{"e3cd10a87f53b2dfa4b5fd606e7d9eca:ACE9d7E606Df5B4AFD2B35f78A01DC3E"}, + name: "valid pattern", + input: ` + # Anypoint Secret Configuration File + # Organization details + ORG_NAME=my_organization + ORG_ID=abcd1234-ef56-gh78-ij90-klmn1234opqr + + # OAuth tokens + CLIENT_ID=e3cd10a87f53b2dfa4b5fd606e7d9eca + CLIENT_SECRET=ACE9d7E606Df5B4AFD2B35f78A01DC3E + + # API keys + SECRET_KEY=1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6 + + # Endpoints + SERVICE_URL=https://api.example.com/v1/resource + `, + want: []string{"e3cd10a87f53b2dfa4b5fd606e7d9eca:ACE9d7E606Df5B4AFD2B35f78A01DC3E"}, }, { - name: "valid pattern - complex", - input: fmt.Sprintf("anypoint credentials: %s", complexPattern), - want: []string{"e3cd10a87f53b2dfa4b5fd606e7d9eca:ACE9d7E606Df5B4AFD2B35f78A01DC3E"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {anypoint id 17c55fba5c93de5646b10507c36fbc23} + {AQAAABAAA 8E6Ef8F8d5De05d8BF1491e1ecC37b31} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"17c55fba5c93de5646b10507c36fbc23:8E6Ef8F8d5De05d8BF1491e1ecC37b31"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("anypoint credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + # Anypoint Secret Configuration File + # Organization details + ORG_NAME=my_organization + ORG_ID=abcd1234-ef56-gh78-ij90-klmn1234opqr + + # OAuth tokens + CLIENT_ID=k4lzc5ty98tnfu3a11y8gnv5vb1281as + CLIENT_SECRET=ACE9d7E606Df5B4AFD2B35f78A01DC3E + + # API keys + SECRET_KEY=1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6 + + # Endpoints + SERVICE_URL=https://api.example.com/v1/resource + `, + want: nil, }, } @@ -67,22 +80,15 @@ func TestAnypoint_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -94,6 +100,7 @@ func TestAnypoint_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apacta/apacta_test.go b/pkg/detectors/apacta/apacta_test.go index 8b6fee13b..b03975ac3 100644 --- a/pkg/detectors/apacta/apacta_test.go +++ b/pkg/detectors/apacta/apacta_test.go @@ -2,47 +2,15 @@ package apacta import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "abcd1234-ef56-gh78-ij90-klmn1234opqr" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - apactaSecret := "Bearer abcd1234-ef56-gh78-ij90-klmn1234opqr" - req.Header.Set("Authorization", apactaSecret) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "abcD$1234-ef56-gH78-ij90-klmn1234opqr" -) - func TestApacta_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,62 @@ func TestApacta_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("apacta credentials: %s", validPattern), - want: []string{"abcd1234-ef56-gh78-ij90-klmn1234opqr"}, + name: "valid pattern", + input: ` + func main() { + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", "https://api.example.com/v1/resource", bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + apactaSecret := "Bearer abcd1234-ef56-gh78-ij90-klmn1234opqr" + req.Header.Set("Authorization", apactaSecret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"abcd1234-ef56-gh78-ij90-klmn1234opqr"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"abcd1234-ef56-gh78-ij90-klmn1234opqr"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apacta} + {AQAAABAAA w8-p59rc70q0unyupknadu5sr8bf5us04mpt} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"w8-p59rc70q0unyupknadu5sr8bf5us04mpt"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("apacta credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", "https://api.example.com/v1/resource", bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + apactaSecret := "Bearer abcD$1234-ef56-gH78-ij90-klmn1234opqr" + req.Header.Set("Authorization", apactaSecret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +84,15 @@ func TestApacta_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +104,7 @@ func TestApacta_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/api2cart/api2cart_test.go b/pkg/detectors/api2cart/api2cart_test.go index c3fa39be9..e31fdb1ad 100644 --- a/pkg/detectors/api2cart/api2cart_test.go +++ b/pkg/detectors/api2cart/api2cart_test.go @@ -2,27 +2,15 @@ package api2cart import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "0123456789abcdef0123456789abcdef" - complexPattern = ` - To integrate with API2Cart, ensure you have the following credentials in your configuration file. Your API2CART key is 1234567890abcdef1234567890abcdef, which you will need to access the API securely. - - The following endpoints are available for your use: - - Get Products: https://api.api2cart.com/v1.0/products/get - - Add Product: https://api.api2cart.com/v1.0/products/add - ` - invalidPattern = "0123456789Gbcde^0123456789abcdef" -) - func TestApi2Cart_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,19 +21,42 @@ func TestApi2Cart_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("api2cart credentials: %s", validPattern), - want: []string{"0123456789abcdef0123456789abcdef"}, + name: "valid pattern", + input: ` + To integrate with API2Cart, ensure you have the following credentials in your configuration file. + Your API2CART key is 2afddb813193eb9d3b5bd99bf5d834cd, which you will need to access the API securely. + + The following endpoints are available for your use: + - Get Products: https://api.api2cart.com/v1.0/products/get + - Add Product: https://api.api2cart.com/v1.0/products/add + `, + want: []string{"2afddb813193eb9d3b5bd99bf5d834cd"}, }, { - name: "valid pattern -complex", - input: complexPattern, - want: []string{"1234567890abcdef1234567890abcdef"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {api2cart} + {AQAAABAAA b36c17e9dc0dba67480e864cf69879c3} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"b36c17e9dc0dba67480e864cf69879c3"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("api2cart credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + To integrate with API2Cart, ensure you have the following credentials in your configuration file. + Your API2CART key is 68d746609J4240840734c22836725d76, which you will need to access the API securely. + + The following endpoints are available for your use: + - Get Products: https://api.api2cart.com/v1.0/products/get + - Add Product: https://api.api2cart.com/v1.0/products/add + `, + want: nil, }, } @@ -53,22 +64,15 @@ func TestApi2Cart_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -80,6 +84,7 @@ func TestApi2Cart_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apideck/apideck_test.go b/pkg/detectors/apideck/apideck_test.go index 268ad1b0b..dc8f05074 100644 --- a/pkg/detectors/apideck/apideck_test.go +++ b/pkg/detectors/apideck/apideck_test.go @@ -2,22 +2,15 @@ package apideck import ( "context" - "fmt" - "strings" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validKeyPattern = "sk_live_abc123def456ghi789jklmno123456pqrstuvwxyz-1234567890123456789012345678901234567890AAui09pU8as" - validIdPattern = "apideck_id: 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t" - invalidPattern = strings.ReplaceAll(validKeyPattern, "sk_live", "sk_inactive") + strings.ReplaceAll(validIdPattern, "1", "$") -) - func TestApiDeck_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -28,16 +21,40 @@ func TestApiDeck_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("credentials: %s \n %s", validKeyPattern, validIdPattern), + name: "valid pattern", + input: ` + [INFO] Sending request to the apideck API + [DEBUG] Using Key=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 + [DEBUG] Using apideck ID=VfKE9Zh2ZatnqmrloqDu3PCnkNBR6Io4TlSbsG1P + [INFO] Response received: 200 OK + `, want: []string{ - validKeyPattern + "1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t", + "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", }, }, { - name: "invalid pattern", - input: fmt.Sprintf("credentials: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apideck id J6rYP2lzThxp9JeGg74TDgAXvfQsvzonsHpYHDsG} + {apideck AQAAABAAA sk_live_R5S2B88smT6QfTsUc3o3DedI2hbbcnZwvQKjyudQ41V0T38L8qUDPUTlBDcVE2NwRp1PowPYqnmAHlZ-W1Yr7AWGvpCvT} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"sk_live_R5S2B88smT6QfTsUc3o3DedI2hbbcnZwvQKjyudQ41V0T38L8qUDPUTlBDcVE2NwRp1PowPYqnmAHlZ-W1Yr7AWGvpCvTJ6rYP2lzThxp9JeGg74TDgAXvfQsvzonsHpYHDsG"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the apideck API + [DEBUG] Using Key=sk_live_GKE08ADdkDV1DQ4vDfaW4ejDHy-TkotfxDmHvQMLX0HRvhtfPwku6olGvsG2vXBg869A0hsOPHHOw48SAF2GO7jBMs6Rt + [DEBUG] Using apideck ID=VfKE9Zh2ZatnqmrloqDu3PC_kNBR6Io4TlSbsG1P + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -45,22 +62,15 @@ func TestApiDeck_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -72,6 +82,7 @@ func TestApiDeck_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apiflash/apiflash_test.go b/pkg/detectors/apiflash/apiflash_test.go index 87e8b3b0c..a90840fb2 100644 --- a/pkg/detectors/apiflash/apiflash_test.go +++ b/pkg/detectors/apiflash/apiflash_test.go @@ -2,22 +2,15 @@ package apiflash import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - apiflash_key: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 - ` - invalidPattern = "0123456789Gbcde^0123456789abcdef" -) - func TestApiFlash_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -28,14 +21,36 @@ func TestApiFlash_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("apiflash credentials: %s", validPattern), - want: []string{"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the apiflash API + [DEBUG] Using Key=grevetn5owrs1ybhxtcen0ibvg2mi85x + [INFO] Response received: 200 OK + `, + want: []string{"grevetn5owrs1ybhxtcen0ibvg2mi85x"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("apiflash credentials: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apiflash} + {AQAAABAAA axlzvcf9m7jyyts833f9gmtcpqe5b26o} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"axlzvcf9m7jyyts833f9gmtcpqe5b26o"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the apiflash API + [DEBUG] Using Key=grevetn5owRs1ybhxtcen0ibvg2mi85x + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -43,22 +58,15 @@ func TestApiFlash_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -70,6 +78,7 @@ func TestApiFlash_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apifonica/apifonica_test.go b/pkg/detectors/apifonica/apifonica_test.go index 684ce6556..cd0f91c41 100644 --- a/pkg/detectors/apifonica/apifonica_test.go +++ b/pkg/detectors/apifonica/apifonica_test.go @@ -2,20 +2,15 @@ package apifonica import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "abc123def45-gh67-ij89-kl01-mn234op56789" - invalidPattern = "0123456789Gbcde^0123456789abcdef" -) - func TestApiFonica_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,14 +21,36 @@ func TestApiFonica_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("apifonica credentials: %s", validPattern), - want: []string{"abc123def45-gh67-ij89-kl01-mn234op56789"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the apifonica API + [DEBUG] Using Key=4rv0hdx5188-3q48-2luk-e8v5-dyuuf8l44ib7 + [INFO] Response received: 200 OK + `, + want: []string{"4rv0hdx5188-3q48-2luk-e8v5-dyuuf8l44ib7"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("apifonica credentials: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apifonica} + {AQAAABAAA fvzlzj17xzz-lwon-842u-46bs-5spcl2g7u9eb} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"fvzlzj17xzz-lwon-842u-46bs-5spcl2g7u9eb"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the apifonica API + [DEBUG] Using Key=4rv0hdx51889-3q48-2luk-e8wv5-dyuuf8l44ib7 + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -41,22 +58,15 @@ func TestApiFonica_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -68,6 +78,7 @@ func TestApiFonica_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apify/apify_test.go b/pkg/detectors/apify/apify_test.go index 15798000a..3e533031c 100644 --- a/pkg/detectors/apify/apify_test.go +++ b/pkg/detectors/apify/apify_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "apify_api_ab12CD34ef56GH78ij90KL12mn34OP56qr78" - invalidPattern = "apify_api_ab12C#34ef56GH7$ij90KL12mn34OP56qr7)" -) - func TestApiFy_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestApiFy_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{validPattern}, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using Key=apify_api_dXB1vLsglgTexUYm3JTAx2BHTjVuDBbvPl8R + [INFO] Response received: 200 OK + `, + want: []string{"apify_api_dXB1vLsglgTexUYm3JTAx2BHTjVuDBbvPl8R"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {user-id} + {AQAAABAAA apify_api_RpTLEX9U18xfGl90wDaT2V9R-YX0TlMpxIzi} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"apify_api_RpTLEX9U18xfGl90wDaT2V9R-YX0TlMpxIzi"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using Key=apify_api_dXB1vLPglgTex_UYm3JTAx2BHTjVuDBbvPl8R + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestApiFy_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestApiFy_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apilayer/apilayer_test.go b/pkg/detectors/apilayer/apilayer_test.go index 7c369b411..3e9cef682 100644 --- a/pkg/detectors/apilayer/apilayer_test.go +++ b/pkg/detectors/apilayer/apilayer_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "apilayerkey: abcdef1234567890abcdef1234567890" - invalidPattern = "apilayerkey: abcdef123$5678*0abcde()1234567890)" -) - func TestApiLayer_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestApiLayer_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"abcdef1234567890abcdef1234567890"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the apilayer API + [DEBUG] Using Key=qnHT110fihCn49wOm5b2h3ACTRmksbg0 + [INFO] Response received: 200 OK + `, + want: []string{"qnHT110fihCn49wOm5b2h3ACTRmksbg0"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apilayer} + {AQAAABAAA HHTi3DYZIqt57j5WVHvXHHboXpCnm6CW} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"HHTi3DYZIqt57j5WVHvXHHboXpCnm6CW"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the apilayer API + [DEBUG] Using Key=qnHT110fiha-Cn49wOm5b2h3ACTRmksbg0 + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestApiLayer_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestApiLayer_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apimatic/apimatic_test.go b/pkg/detectors/apimatic/apimatic_test.go index 09a35794d..368a481b0 100644 --- a/pkg/detectors/apimatic/apimatic_test.go +++ b/pkg/detectors/apimatic/apimatic_test.go @@ -5,22 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - func validateApiMatic() bool { - apiMaticKey := "rc6iLoUEFGGAWNLsuBJnmsh4tZB-oCxcDUmc45HIPcuiQvfUEuqo8wb9YrUd2LyB" - - return isActive(apiMaticKey, apiMaticPass) - } - ` - invalidPattern = "apiMaticKey: rc6iL$UEFGGAWNLsuBJnmsh4tZB)oCxcDUmc45HIPcuiQvfUEuqo8wb9YrUd2LyB" -) - func TestApiMatic_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -31,14 +21,40 @@ func TestApiMatic_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"rc6iLoUEFGGAWNLsuBJnmsh4tZB-oCxcDUmc45HIPcuiQvfUEuqo8wb9YrUd2LyB"}, + name: "valid pattern", + input: ` + func validateApiMatic() bool { + apiMaticKey := "rc6iLoUEFGGAWNLsuBJnmsh4tZB-oCxcDUmc45HIPcuiQvfUEuqo8wb9YrUd2LyB" + + // isActive check if the key is active or not + return isActive(apiMaticKey) + }`, + want: []string{"rc6iLoUEFGGAWNLsuBJnmsh4tZB-oCxcDUmc45HIPcuiQvfUEuqo8wb9YrUd2LyB"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apimatic} + {AQAAABAAA 2eqQBh9HkE-5Mq5Ma_vOEvvyt-x9shcZ-T5B7hSY1C5xvTl7qLMwGL6QAoNYmMcF} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"2eqQBh9HkE-5Mq5Ma_vOEvvyt-x9shcZ-T5B7hSY1C5xvTl7qLMwGL6QAoNYmMcF"}, + }, + { + name: "invalid pattern", + input: ` + func validateApiMatic() bool { + apiMaticKey := "rc6iLoUEFGGAWNLsuBJnmsh4tZB@oCxcDUmc45HIPcuiQvfUEuqo8wb9YrUd2LyB" + + // isActive check if the key is active or not + return isActive(apiMaticKey) + }`, + want: nil, }, } @@ -46,22 +62,15 @@ func TestApiMatic_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +82,7 @@ func TestApiMatic_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apimetrics/apimetrics_test.go b/pkg/detectors/apimetrics/apimetrics_test.go index 93e780ba1..b23c6de10 100644 --- a/pkg/detectors/apimetrics/apimetrics_test.go +++ b/pkg/detectors/apimetrics/apimetrics_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "apimetricskey: 5po8TFGawiYNCc1ct4ofWkBqzIfA6IeO" - invalidPattern = "apimetricskey: A1b2C3d4 E5f6G7h8I9 j0K1l2M3n4O5p6" -) - func TestApiMetrics_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,40 @@ func TestApiMetrics_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"5po8TFGawiYNCc1ct4ofWkBqzIfA6IeO"}, + name: "valid pattern", + input: ` + func validateApiMetrics() bool { + apiMetrics := "5po8TFGawiYNCc1ct4ofWkBqzIfA6IeO" + + // isActive check if the key is active or not + return isActive(apiMetrics) + }`, + want: []string{"5po8TFGawiYNCc1ct4ofWkBqzIfA6IeO"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apimetrics} + {AQAAABAAA XpLTBFZccOgbbtVht4OaZzsrgKdh42RX} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"XpLTBFZccOgbbtVht4OaZzsrgKdh42RX"}, + }, + { + name: "invalid pattern", + input: ` + func validateApiMetrics() bool { + apiMetrics := "5po8TFGawiYNCc1c4ofWkBqzIfA6IeO" + + // isActive check if the key is active or not + return isActive(apiMetrics) + }`, + want: nil, }, } @@ -40,22 +62,15 @@ func TestApiMetrics_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +82,7 @@ func TestApiMetrics_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apitemplate/apitemplate_test.go b/pkg/detectors/apitemplate/apitemplate_test.go index e19fce97e..057fb63e9 100644 --- a/pkg/detectors/apitemplate/apitemplate_test.go +++ b/pkg/detectors/apitemplate/apitemplate_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "apitemplatekey: a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T" - invalidPattern = "apitemplatekey: sk_0C2c3D4e5F6@7H8i9J$k1L2m3N4o5P6q7R8s9T" -) - func TestApiTemplate_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,40 @@ func TestApiTemplate_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T"}, + name: "valid pattern", + input: ` + func validateKey() bool { + apiTemplate := "EeOPHL7PyBlUk0qkJX72sDtdNL3WLdpxg1czllR" + + // isActive check if the key is active or not + return isActive(apiTemplate) + }`, + want: []string{"EeOPHL7PyBlUk0qkJX72sDtdNL3WLdpxg1czllR"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apitemplate} + {AQAAABAAA oVqX8yfzlUtzudNnvlWKNI4pNKTKTwlaKmxlcX5} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"oVqX8yfzlUtzudNnvlWKNI4pNKTKTwlaKmxlcX5"}, + }, + { + name: "invalid pattern", + input: ` + func validateKey() bool { + apiTemplate := "EeOPHL7PyBlUk0qkJAX72sDtdNL3WLdpxg1czllR" + + // isActive check if the key is active or not + return isActive(apiTemplate) + }`, + want: nil, }, } @@ -40,22 +62,15 @@ func TestApiTemplate_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +82,7 @@ func TestApiTemplate_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apollo/apollo_test.go b/pkg/detectors/apollo/apollo_test.go index c66ba5417..b7934d230 100644 --- a/pkg/detectors/apollo/apollo_test.go +++ b/pkg/detectors/apollo/apollo_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "apollo: A1b2C3d4E5f6G7h8I9j0K1" - invalidPattern = "apollo: A1b2C3d4-5f6G7h8I9j0K1@$" -) - func TestApollo_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,52 @@ func TestApollo_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"A1b2C3d4E5f6G7h8I9j0K1"}, + name: "valid pattern", + input: ` + func validateApolloKey() bool { + apiKey := "897TJ1HevanW9Ye6nv6Ojj" + log.Println("Checking API key status...") + + if !isActive(apiKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: []string{"897TJ1HevanW9Ye6nv6Ojj"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apollo} + {AQAAABAAA S2wg2NMlgalg9AUsrXPd1O} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"S2wg2NMlgalg9AUsrXPd1O"}, + }, + { + name: "invalid pattern", + input: ` + func validateApolloKey() bool { + apiKey := "897TJ1HevanW9Ye-nv6Ojj" + log.Println("Checking API key status...") + + if !isActive(apiKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: nil, }, } @@ -40,22 +74,15 @@ func TestApollo_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +94,7 @@ func TestApollo_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/appcues/appcues_test.go b/pkg/detectors/appcues/appcues_test.go index a239edfac..a8b037d93 100644 --- a/pkg/detectors/appcues/appcues_test.go +++ b/pkg/detectors/appcues/appcues_test.go @@ -5,24 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - appcues abcdef12-3456-7890-1234-56789abcdef0 - appcues abcdef123456789012345678901234567890123 - appcues 12345 - ` - invalidPattern = ` - appcues abcdef12#3456-7890-1234-56789abcdef0 - appcues abcdef12345678901&345678901234567890123 - appcues 123456 - ` -) - func TestAppCues_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,14 +21,41 @@ func TestAppCues_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"abcdef12-3456-7890-1234-56789abcdef0abcdef123456789012345678901234567890123"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the appcues API + [DEBUG] Using appcues Key=5g5n4yazu-dpqp3g6qt3gn59wrxhqf2mqipm + [DEBUG] Using appcues User=truffle-security-lrv10a8l4u23xp5gkvg819 + [INFO] Response received: 200 OK + [INFO] APPCUES_ID=57843 + `, + want: []string{"5g5n4yazu-dpqp3g6qt3gn59wrxhqf2mqipmtruffle-security-lrv10a8l4u23xp5gkvg819"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {appcues 91712} + {appcues ubdcpht45hlfdywxv89ympnvtcnydl3uv-0umfu} + {appcues AQAAABAAA w9hyyfghqirj8uwcmtv05-n4fppzl-in223u} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"w9hyyfghqirj8uwcmtv05-n4fppzl-in223uubdcpht45hlfdywxv89ympnvtcnydl3uv-0umfu"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the appcues API + [DEBUG] Using appcues Key=5g5n4yazu-dpqp3g6qt3gn59wrxhqf2mqipm + [DEBUG] Using appcues User=truffle_security-lrv10a8l4u23xp5gkvg819 + [ERROR] Response received: 401 UnAuthorized + [INFO] ID=57843 + `, + want: nil, }, } @@ -48,22 +63,15 @@ func TestAppCues_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +83,7 @@ func TestAppCues_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/appfollow/appfollow_test.go b/pkg/detectors/appfollow/appfollow_test.go index 7427ccde3..7ccf4709b 100644 --- a/pkg/detectors/appfollow/appfollow_test.go +++ b/pkg/detectors/appfollow/appfollow_test.go @@ -2,20 +2,15 @@ package appfollow import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.333HbjEo1oxVUFcASR0sQ8cMuIJRLcMd5H9iJWDbovCw6ESjNtuoEMQQGPN9aSoxponxrTPvn1.btADhgNetsaUBuwoyHo5ip0Jab6N6MEBnSaT6CHiO6z" - invalidPattern = "eyQ0eXAiOiJMM1QiLDJhbGciOiJIUXI1NiK7.abcdefgh1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcd1234efgh5678ijkl9012.qwerty12345-ASDFG67890_zxcvb_ABCDE" -) - func TestAppFollow_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,14 +21,46 @@ func TestAppFollow_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("appfollow credential: %s", validPattern), - want: []string{"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.333HbjEo1oxVUFcASR0sQ8cMuIJRLcMd5H9iJWDbovCw6ESjNtuoEMQQGPN9aSoxponxrTPvn1.btADhgNetsaUBuwoyHo5ip0Jab6N6MEBnSaT6CHiO6z"}, + name: "valid pattern", + input: ` + func validateAppFollowKey() bool { + key := "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.hdMLjiIayyb5cgbcVtjKywQwqeNKnsxZEhnJnX6wzhnblpmpjF4c2mbdmVVylTayE6M8ZE3h4V.fmnUM4cjvbe1JMFDuBSwWNEYQFHrD5AEm6p2Ir9w7K6" + + // isActive check if the key is active or not + return isActive(key) + }`, + want: []string{"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.hdMLjiIayyb5cgbcVtjKywQwqeNKnsxZEhnJnX6wzhnblpmpjF4c2mbdmVVylTayE6M8ZE3h4V.fmnUM4cjvbe1JMFDuBSwWNEYQFHrD5AEm6p2Ir9w7K6"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("appfollow credential: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {appfollow} + {AQAAABAAA eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.YwK6gJ8sMVylaDNuXRiGFLRR1kgZaLF45EbJ0qHSRaW4CRtWaqWciTZZXxkk4a4wLh8f7cTTlb.wvTVCRC1RLCpd98q4WK3ef6M3TBrb08AkS9-jNOdA_r} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.YwK6gJ8sMVylaDNuXRiGFLRR1kgZaLF45EbJ0qHSRaW4CRtWaqWciTZZXxkk4a4wLh8f7cTTlb.wvTVCRC1RLCpd98q4WK3ef6M3TBrb08AkS9-jNOdA_r"}, + }, + { + name: "invalid pattern", + input: ` + func validateAppFollowKey() bool { + apiKey := "eyJ0eXAiOiJKV1QiLCJhbGCiOiJIUzI1NiJ9.hdMLjiIayyb5cgbcVtjKywQwqeNKnsxZEhnJnX6wzhnblpmpjF4c2mbdVylTayE6M8ZE3h4V.fmnUM4cjvbe1JMFDuBSwWNEYQFHrDEm6p2Ir9w7K6" + log.Println("Checking API key status...") + + if !isActive(apiKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: nil, }, } @@ -41,22 +68,15 @@ func TestAppFollow_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -68,6 +88,7 @@ func TestAppFollow_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/appointedd/appointedd_test.go b/pkg/detectors/appointedd/appointedd_test.go index 462854b56..f554ce2e5 100644 --- a/pkg/detectors/appointedd/appointedd_test.go +++ b/pkg/detectors/appointedd/appointedd_test.go @@ -2,20 +2,15 @@ package appointedd import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "Ci0a2bSpRyFcZyEXBEr9RHzf3xXllqO=XVoh+t0L0s8T2s3MFntfWhBlovqLaqEadtuJ9=Jy6yCOXmhbpEZPfY7Y" - invalidPattern = "Ci0a2bSpRyFcZyEXBEr9RHzf3xXllqO^XVoh+t0L0s8T2s3MFntfWhBlovqLaqEadtuJ9$Jy6yCOXmhbpEZPfY7Y" -) - func TestAppFollow_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,14 +21,52 @@ func TestAppFollow_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("appointedd credential: %s", validPattern), - want: []string{"Ci0a2bSpRyFcZyEXBEr9RHzf3xXllqO=XVoh+t0L0s8T2s3MFntfWhBlovqLaqEadtuJ9=Jy6yCOXmhbpEZPfY7Y"}, + name: "valid pattern", + input: ` + func validateAppointeddKey() bool { + appointeddKey := "Ci0a2bSpRyFcZyEXBEr9RHzf3xXllqO=XVoh+t0L0s8T2s3MFntfWhBlovqLaqEadtuJ9=Jy6yCOXmhbpEZPfY7Y" + log.Println("Checking API key status...") + + if !isActive(appointeddKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: []string{"Ci0a2bSpRyFcZyEXBEr9RHzf3xXllqO=XVoh+t0L0s8T2s3MFntfWhBlovqLaqEadtuJ9=Jy6yCOXmhbpEZPfY7Y"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("appointedd credential: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {appointedd} + {AQAAABAAA 2pRMKW=JrG9+xYmqlJMa4Omf9goqsSqsM3mIaqG8tG4lwnVrKIslbn=IpLIz7GTDEJUcQ0wlr6B+UjfvSY9XKXwu} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"2pRMKW=JrG9+xYmqlJMa4Omf9goqsSqsM3mIaqG8tG4lwnVrKIslbn=IpLIz7GTDEJUcQ0wlr6B+UjfvSY9XKXwu"}, + }, + { + name: "invalid pattern", + input: ` + func validateAppointeddKey() bool { + appointeddKey := "Ci0a2bSpRyFcZyEXBEr9RHzf3xXllqO-XVoh+t0L0s8T2s3MFntfWhBlovqLaqEadtuJ9-Jy6yCOXmhbpEZPfY7Y" + log.Println("Checking API key status...") + + if !isActive(appointeddKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: nil, }, } @@ -41,22 +74,15 @@ func TestAppFollow_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -68,6 +94,7 @@ func TestAppFollow_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/appoptics/appoptics_test.go b/pkg/detectors/appoptics/appoptics_test.go index 41920ae59..a29bfd069 100644 --- a/pkg/detectors/appoptics/appoptics_test.go +++ b/pkg/detectors/appoptics/appoptics_test.go @@ -2,20 +2,15 @@ package appoptics import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "IABJPR08RmvsGrebJhr1TUdo27-KtTn0mLCKkJJqj5lyba-otXPklygO9DK62o3QSPoIJ4E" - invalidPattern = "IABJPR08Rmvs.GrebJhr1TUdo27_KtTn0mLCKkJJqj5lyba&otXPklygO9DK62o3QSPoIJ4E" -) - func TestAppOptics_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,14 +21,52 @@ func TestAppOptics_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("appoptics credential: %s", validPattern), - want: []string{"IABJPR08RmvsGrebJhr1TUdo27-KtTn0mLCKkJJqj5lyba-otXPklygO9DK62o3QSPoIJ4E"}, + name: "valid pattern", + input: ` + func validateAppOpticsKey() bool { + appopticsKey := "Xwl4ViaAFDLrAmFX9g1blkUVC5dJj2he3a1tzkpJ4-PznQukQruRjqMFbEG73L92LJyBGMZ" + log.Println("Checking API key status...") + + if !isActive(appopticsKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: []string{"Xwl4ViaAFDLrAmFX9g1blkUVC5dJj2he3a1tzkpJ4-PznQukQruRjqMFbEG73L92LJyBGMZ"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("appoptics credential: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {appoptics} + {AQAAABAAA zxsb8yzT0RbIJ1TAalB87LOVUcT1b4uEgvT4tXCcSqv_gcmlrx5aQRleHPDFKePjpHFof5J} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"zxsb8yzT0RbIJ1TAalB87LOVUcT1b4uEgvT4tXCcSqv_gcmlrx5aQRleHPDFKePjpHFof5J"}, + }, + { + name: "invalid pattern", + input: ` + func validateAppOpticsKey() bool { + appopticsKey := "Xwl4ViaAFDLrAmFX9g1blkUVC5dJj2h:3a1tzkpJ43PznQukQruRjqMFbEG73L92LJyBGMZ" + log.Println("Checking API key status...") + + if !isActive(appopticsKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: nil, }, } @@ -41,22 +74,15 @@ func TestAppOptics_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -68,6 +94,7 @@ func TestAppOptics_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/appsynergy/appsynergy_test.go b/pkg/detectors/appsynergy/appsynergy_test.go index 975115c1e..12d63c806 100644 --- a/pkg/detectors/appsynergy/appsynergy_test.go +++ b/pkg/detectors/appsynergy/appsynergy_test.go @@ -2,20 +2,15 @@ package appsynergy import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "mg1pgwlndtq7rbk8i3kum344aso8ggp02ximdhsp8nsqasd3btxf84lz9ekfdpwo" - invalidPattern = "mG1pgwlndtq7rbk8i3kum344a$o8gGp02ximdhsp8nsqasd3btxf84lz9ekfdpwo" -) - func TestAppSynergy_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,14 +21,52 @@ func TestAppSynergy_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("appsynergy credential: %s", validPattern), - want: []string{"mg1pgwlndtq7rbk8i3kum344aso8ggp02ximdhsp8nsqasd3btxf84lz9ekfdpwo"}, + name: "valid pattern", + input: ` + func validateAppSynergyKey() bool { + appSyneregyKey := "mg1pgwlndtq7rbk8i3kum344aso8ggp02ximdhsp8nsqasd3btxf84lz9ekfdpwo" + log.Println("Checking API key status...") + + if !isActive(appSyneregyKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: []string{"mg1pgwlndtq7rbk8i3kum344aso8ggp02ximdhsp8nsqasd3btxf84lz9ekfdpwo"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("appsynergy credential: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {appsynergy} + {AQAAABAAA ri1vn9m2otlg3yi8wwjegltc1t3bi4ljogg6c80onnrox2t9fuim6tce430fhklz} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"ri1vn9m2otlg3yi8wwjegltc1t3bi4ljogg6c80onnrox2t9fuim6tce430fhklz"}, + }, + { + name: "invalid pattern", + input: ` + func validateAppSynergyKey() bool { + appSyneregyKey := "mg1pgwlndtq7rbk8i3kum_44aso8ggp02ximdhsp8nsqasd3btxf84lz9ekfdpwo" + log.Println("Checking API key status...") + + if !isActive(appSyneregyKey) { + log.Println("API key is inactive or invalid.") + return false + } + + log.Println("API key is valid and active.") + return true + }`, + want: nil, }, } @@ -41,22 +74,15 @@ func TestAppSynergy_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -68,6 +94,7 @@ func TestAppSynergy_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/apptivo/apptivo_test.go b/pkg/detectors/apptivo/apptivo_test.go index b2c74f4c4..97b8fb79e 100644 --- a/pkg/detectors/apptivo/apptivo_test.go +++ b/pkg/detectors/apptivo/apptivo_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "apptivokey: 1h3l8yjo3pms2h738k8f9094rkltmgy8md-4 - apptivoID: wV2WGN-KUxROVW0mlq8kur7TbKvCTdNc" - invalidPattern = "apptivokey: 1h3l8yjo3pms2h738k8f9094rkltmgy8md-4" -) - func TestApptivo_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,38 @@ func TestApptivo_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"1h3l8yjo3pms2h738k8f9094rkltmgy8md-4wV2WGN-KUxROVW0mlq8kur7TbKvCTdNc"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the apptivo API + [DEBUG] Using apptivo Key=fox94at7-8dj92ns-cdxhag4470yqp0o2c8y + [DEBUG] Using apptivo ID=C27YfQFKcUue8OxfEiAcqzrPVII-pb3V + [INFO] Response received: 200 OK + `, + want: []string{"fox94at7-8dj92ns-cdxhag4470yqp0o2c8yC27YfQFKcUue8OxfEiAcqzrPVII-pb3V"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {apptivo o9qB77Q9cCXfuV-TWyCWUumiAbZc2Z7i} + {apptivo AQAAABAAA juqc5-sw846p0cj43wy8eex6rr4v8-9oa3dh} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"juqc5-sw846p0cj43wy8eex6rr4v8-9oa3dho9qB77Q9cCXfuV-TWyCWUumiAbZc2Z7i"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the apptivo API + [DEBUG] Using apptivo Key=fOx94aT7-8dj92ns-cdxhag4470yqp0o2c8y + [DEBUG] Using apptivo ID=C27YfQF-cUue8OxfEiAcqzrPVII-pb3V + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +60,15 @@ func TestApptivo_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +80,7 @@ func TestApptivo_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/artifactory/artifactory_test.go b/pkg/detectors/artifactory/artifactory_test.go index 57d2c365d..071d89ffd 100644 --- a/pkg/detectors/artifactory/artifactory_test.go +++ b/pkg/detectors/artifactory/artifactory_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -25,19 +26,38 @@ func TestArtifactory_Pattern(t *testing.T) { { name: "valid pattern", input: ` - # artifactory credentials - Token: cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg - Url: rwxtOp.jfrog.io + [INFO] Sending request to the artifactory API + [DEBUG] Using Key=cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] rwxtOp.jfrog.io + [INFO] Response received: 200 OK `, useCloudEndpoint: false, useFoundEndpoint: true, want: []string{"cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZgrwxtOp.jfrog.io"}, }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {artifactory} + {AQAAABAAA KUd8GOVfcXnIv1nJ5qmnNzrqkLvseoPRMuwsdDVr9QthonFogtMaoJ3pgtO4eHXC} + {HTTPnGQZ79vjWXze.jfrog.io} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + useCloudEndpoint: false, + useFoundEndpoint: true, + want: []string{"KUd8GOVfcXnIv1nJ5qmnNzrqkLvseoPRMuwsdDVr9QthonFogtMaoJ3pgtO4eHXCHTTPnGQZ79vjWXze.jfrog.io"}, + }, { name: "valid pattern - with cloud endpoints", input: ` - # artifactory credentials - Token: cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] Sending request to the artifactory API + [DEBUG] Using Key=cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] Response received: 200 OK `, cloudEndpoint: "cloudendpoint.jfrog.io", useCloudEndpoint: true, @@ -47,9 +67,10 @@ func TestArtifactory_Pattern(t *testing.T) { { name: "valid pattern - with cloud and found endpoints", input: ` - # artifactory credentials - Token: cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg - Url: rwxtOp.jfrog.io + [INFO] Sending request to the artifactory API + [DEBUG] Using Key=cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] rwxtOp.jfrog.io + [INFO] Response received: 200 OK `, cloudEndpoint: "cloudendpoint.jfrog.io", useCloudEndpoint: true, @@ -62,9 +83,10 @@ func TestArtifactory_Pattern(t *testing.T) { { name: "valid pattern - with disabled found endpoints", input: ` - # artifactory credentials - Token: cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg - Url: rwxtOp.jfrog.io + [INFO] Sending request to the artifactory API + [DEBUG] Using Key=cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] rwxtOp.jfrog.io + [INFO] Response received: 200 OK `, cloudEndpoint: "cloudendpoint.jfrog.io", useCloudEndpoint: true, @@ -76,8 +98,9 @@ func TestArtifactory_Pattern(t *testing.T) { { name: "valid pattern - with https in configured endpoint", input: ` - # artifactory credentials - Token: cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] Sending request to the artifactory API + [DEBUG] Using Key=cmVmdGtuOjAxOjE3ODA1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] Response received: 200 OK `, cloudEndpoint: "https://cloudendpoint.jfrog.io", useCloudEndpoint: true, @@ -89,9 +112,10 @@ func TestArtifactory_Pattern(t *testing.T) { { name: "invalid pattern", input: ` - # artifactory credentials - Token: cmVmdGtuOjAxOjE3ODA_NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg - Url: rwxtOp.jfroq.io + [INFO] Sending request to the artifactory API + [DEBUG] Using Key=cmVmdGtuOjAxOjEODA_1NTFAKEM6S2J2MGswemNzZzhaRnFlVUFAKEk3amlLcGZg + [INFO] rwxtOp.jfrog.io + [INFO] Response received: 200 OK `, useFoundEndpoint: true, want: nil, @@ -110,22 +134,15 @@ func TestArtifactory_Pattern(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -137,6 +154,7 @@ func TestArtifactory_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/artsy/artsy_test.go b/pkg/detectors/artsy/artsy_test.go index 3ac7c892d..2d0bd184a 100644 --- a/pkg/detectors/artsy/artsy_test.go +++ b/pkg/detectors/artsy/artsy_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "artsy_key: rU0K6hwGw9AeANtXrZ8FQJT9jn4sRdlj - artsy_id: hvQ2fMvUPNczDCdmzi0i" - invalidPattern = "artsy_key: rU:K6hwGw9AeANtXrZ8F%JT9jn4sR,lj - artsy_id: hvQ2f-vUPNczD+dmzi0i" -) - func TestArtsy_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,38 @@ func TestArtsy_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"rU0K6hwGw9AeANtXrZ8FQJT9jn4sRdljhvQ2fMvUPNczDCdmzi0i"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the artsy API + [DEBUG] Using Key=rU0K6hwGw9AeANtXrZ8FQJT9jn4sRdlj + [DEBUG] Using artsy ID=hvQ2fMvUPNczDCdmzi0i + [INFO] Response received: 200 OK + `, + want: []string{"rU0K6hwGw9AeANtXrZ8FQJT9jn4sRdljhvQ2fMvUPNczDCdmzi0i"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {artsy Mbw4Tihfv1ttrspD1yXk} + {artsy AQAAABAAA 3V4gtw8ZmDShAfzq2KKb3w0gZODnzxp7} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"3V4gtw8ZmDShAfzq2KKb3w0gZODnzxp7Mbw4Tihfv1ttrspD1yXk"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the artsy API + [DEBUG] Using Key=rU0K6hwGw9AeANtX-Z8FQJT9jn4sRdlj + [DEBUG] Using artsy ID=hvQ2fMvUPN_zDCdmzi0i + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +60,15 @@ func TestArtsy_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +80,7 @@ func TestArtsy_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/asanaoauth/asanaoauth_test.go b/pkg/detectors/asanaoauth/asanaoauth_test.go index ff9e64ddb..bea3efe94 100644 --- a/pkg/detectors/asanaoauth/asanaoauth_test.go +++ b/pkg/detectors/asanaoauth/asanaoauth_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "asana_key: v1e0uwkmv2ykvsu998lqe4g7ij2gwtg/xn9vh4jvsokdfaic0bn" - invalidPattern = "asana_key: v1e0uwkmv2ykvsu998lqe4g-ij2gwtg/xn9vh4jvsokdfaic0bn" -) - func TestAsanaOauth_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAsanaOauth_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"v1e0uwkmv2ykvsu998lqe4g7ij2gwtg/xn9vh4jvsokdfaic0bn"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the asana API + [DEBUG] Using Key=q5przi0tmp6xpo7rpsd0q:kl0qg:2gdj3jyumq04q9kcqk/qxdo + [INFO] Response received: 200 OK + `, + want: []string{"q5przi0tmp6xpo7rpsd0q:kl0qg:2gdj3jyumq04q9kcqk/qxdo"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {asana} + {AQAAABAAA omzmg54nn5wa21sh6qwg:dos10bfl1f6vnqcs9lcdwkbqb68gti} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"omzmg54nn5wa21sh6qwg:dos10bfl1f6vnqcs9lcdwkbqb68gti"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the asana API + [DEBUG] Using Key=q5przi0tmP6xpo7rpsd0q;kl0qg:2gdj3jyumq04q9kcqk/qxdo + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAsanaOauth_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAsanaOauth_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/asanapersonalaccesstoken/asanapersonalaccesstoken_test.go b/pkg/detectors/asanapersonalaccesstoken/asanapersonalaccesstoken_test.go index cf8fde9f3..8e17f7185 100644 --- a/pkg/detectors/asanapersonalaccesstoken/asanapersonalaccesstoken_test.go +++ b/pkg/detectors/asanapersonalaccesstoken/asanapersonalaccesstoken_test.go @@ -5,19 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - // Old format token - validPatternOld = "asana_token: 594776654034514343561917591881414702593902454625364993/1724908107002616220416212965:Yv3DoiSFhtsgUwN3AcnXWjK8zabQHKSHBRHpuNKVjz3oCcpyDIdXRm3GL4SUDkTMFoTbRDCHe8tTBHxdtoXItn" - // New format token with two forward slashes - newValidPattern = "asana_token: 7/9823746598123746/8923746598123456:7f1a3c9be84d2a6c4e7d9c32bf1e7f88" - invalidPattern = "asana_token: 1724908107002616220416212965%594776654034514343561917591881414702593902454625364993:Yv3DoiSFhtsgUwN3AcnXWjK8zabQHKSHBRHpuNKVjz3oCcpyDIdXRm3GL4SUDkTMFoTbRDCHe8tTBHxdtoXItn-ij2gwtg/xn9vh4jvsokdfaic0bn" -) - func TestAsanaPersonalAccessToken_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -28,19 +21,43 @@ func TestAsanaPersonalAccessToken_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern - old format", - input: validPatternOld, - want: []string{"594776654034514343561917591881414702593902454625364993/1724908107002616220416212965:Yv3DoiSFhtsgUwN3AcnXWjK8zabQHKSHBRHpuNKVjz3oCcpyDIdXRm3GL4SUDkTMFoTbRDCHe8tTBHxdtoXItn"}, + name: "valid pattern - old format", + input: ` + [INFO] Sending request to the asana API + [DEBUG] Using Old Format asana Key=5947/1724908107002616220416212965:Yv3DoiSFhtsgUwN3AcnXWjK8zabQHKSHBRHpuNKVjz3oCcpyDIdXRm3GL4SUDkTMFoTb + [ERROR] Response received: 400 BadRequest + [DEBUG] Using new format asana Key=7/9823746598123746/8923746598123456:7f1a3c9be84d2a6c4e7d9c32bf1e7f88 + [INFO] Response received: 200 OK + `, + want: []string{ + "5947/1724908107002616220416212965:Yv3DoiSFhtsgUwN3AcnXWjK8zabQHKSHBRHpuNKVjz3oCcpyDIdXRm3GL4SUDkTMFoTb", + "7/9823746598123746/8923746598123456:7f1a3c9be84d2a6c4e7d9c32bf1e7f88", + }, }, { - name: "valid pattern - new format", - input: newValidPattern, - want: []string{"7/9823746598123746/8923746598123456:7f1a3c9be84d2a6c4e7d9c32bf1e7f88"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {asana} + {AQAAABAAA 891435852083139681602524390768273271357927849104481/366163755073364840345913922341185329292536814045275090976491644844014597476863956806652784056747/17480879147700616278211801017829125:Hb7meGPLBz7jH7e1fiHetN355omiO9Zt8fewjSOX4qfUoWDzvvlNA6lBx9rNuR8EAEElmtmmL9J4ilO8m2D56n} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"891435852083139681602524390768273271357927849104481/366163755073364840345913922341185329292536814045275090976491644844014597476863956806652784056747/17480879147700616278211801017829125:Hb7meGPLBz7jH7e1fiHetN355omiO9Zt8fewjSOX4qfUoWDzvvlNA6lBx9rNuR8EAEElmtmmL9J4ilO8m2D56n"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + [INFO] Sending request to the asana API + [DEBUG] Using Old Format asana Key=5947766540345/172490810700261:Yv3DoiSFhjK8zabQHKSHBRHpuNKVjz3oCcpyDIdXRm3GL4SUDkTMFoTbRDCHe8tTBHxdtoXItn + [ERROR] Response received: 400 BadRequest + [DEBUG] Using new format asana Key=7/98237465/8923746598156:7f1a3c9be84d2a6c4e7d9c32bf1e7f88 + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -48,22 +65,15 @@ func TestAsanaPersonalAccessToken_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +85,7 @@ func TestAsanaPersonalAccessToken_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/assemblyai/assemblyai_test.go b/pkg/detectors/assemblyai/assemblyai_test.go index 5d9dac960..2d00f673a 100644 --- a/pkg/detectors/assemblyai/assemblyai_test.go +++ b/pkg/detectors/assemblyai/assemblyai_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "assemblyai: mlhekyjhs96mx0r2cxbzky4jzr83fw1q" - invalidPattern = "assemblyai: Mlhekyjzr83fw1qr2cxbzky4jzr83f1q" -) - func TestAssemblyAI_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAssemblyAI_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"mlhekyjhs96mx0r2cxbzky4jzr83fw1q"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using assemblyai Key=mlhekyjhs96mx0r2cxbzky4jzr83fw1q + [INFO] Response received: 200 OK + `, + want: []string{"mlhekyjhs96mx0r2cxbzky4jzr83fw1q"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {assemblyai} + {AQAAABAAA s0c8a99g0w6qbwybdxn4uowzemk1xlca} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"s0c8a99g0w6qbwybdxn4uowzemk1xlca"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using assemblyai Key=Mlhekyjzr83fw1qr2cxbzky4jzr83f1q + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAssemblyAI_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAssemblyAI_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/atera/atera_test.go b/pkg/detectors/atera/atera_test.go index e2000a2d6..f6e46d158 100644 --- a/pkg/detectors/atera/atera_test.go +++ b/pkg/detectors/atera/atera_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "atera_key: yoo3d5pu3t4zxd6x1vhk7ykmjqarbsv1" - invalidPattern = "atera_key: yOO3d5pu3t4zxd6x1vhk7ykmjqarbs_1" -) - func TestAtera_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAtera_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"yoo3d5pu3t4zxd6x1vhk7ykmjqarbsv1"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the atera API + [DEBUG] Using Key=yoo3d5pu3t4zxd6x1vhk7ykmjqarbsv1 + [INFO] Response received: 200 OK + `, + want: []string{"yoo3d5pu3t4zxd6x1vhk7ykmjqarbsv1"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {atera} + {AQAAABAAA uvyn0qy0ec96pgxfr2s3i4bqv1znl7yg} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"uvyn0qy0ec96pgxfr2s3i4bqv1znl7yg"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the atera API + [DEBUG] Using Key=yOO3d5pu3t4zxd6x1vhk7ykmjqarbs_1 + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAtera_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAtera_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/atlassian/v1/atlassian_test.go b/pkg/detectors/atlassian/v1/atlassian_test.go index 29984495d..335f4bdaa 100644 --- a/pkg/detectors/atlassian/v1/atlassian_test.go +++ b/pkg/detectors/atlassian/v1/atlassian_test.go @@ -2,10 +2,12 @@ package atlassian import ( "context" + "testing" + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" - "testing" ) func TestAtlassian_Pattern(t *testing.T) { @@ -17,9 +19,27 @@ func TestAtlassian_Pattern(t *testing.T) { want []string }{ { - name: "typical pattern", - input: "atlassian = 'aB1cD2eF3gH4iJ5kL6mN7oP8'", - want: []string{"aB1cD2eF3gH4iJ5kL6mN7oP8"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the atlassian API + [DEBUG] Using Key=aB1cD2eF3gH4iJ5kL6mN7oP8 + [INFO] Response received: 200 OK + `, + want: []string{"aB1cD2eF3gH4iJ5kL6mN7oP8"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {atlassian} + {AQAAABAAA r6RkiQao3PgqY9MOKtonpJdU} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"r6RkiQao3PgqY9MOKtonpJdU"}, }, } @@ -27,22 +47,15 @@ func TestAtlassian_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -54,6 +67,7 @@ func TestAtlassian_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/atlassian/v2/atlassian_test.go b/pkg/detectors/atlassian/v2/atlassian_test.go index de1093f9f..b176c8692 100644 --- a/pkg/detectors/atlassian/v2/atlassian_test.go +++ b/pkg/detectors/atlassian/v2/atlassian_test.go @@ -2,10 +2,12 @@ package atlassian import ( "context" + "testing" + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" - "testing" ) func TestAtlassian_Pattern(t *testing.T) { @@ -17,9 +19,27 @@ func TestAtlassian_Pattern(t *testing.T) { want []string }{ { - name: "typical pattern", - input: "atlassian = 'ATCTT3xFfGN0GsZNgOGrQSHSnxiJVi00oHlRicyM0yMNuKCBfw6qOHVcCy4Hm89GnclGb_W-1qAkxqCn5XbuyoX54bNhpK5yFKGFR7ocV6FByvL_P9Sb3tFnbUg3T3I3S_RGCBLMSN7Nsa4GJv8JEJ6bzvDmX-oJ8AnrazMU-zZ5hb-u3t2ERew=366BFE3A'", - want: []string{"ATCTT3xFfGN0GsZNgOGrQSHSnxiJVi00oHlRicyM0yMNuKCBfw6qOHVcCy4Hm89GnclGb_W-1qAkxqCn5XbuyoX54bNhpK5yFKGFR7ocV6FByvL_P9Sb3tFnbUg3T3I3S_RGCBLMSN7Nsa4GJv8JEJ6bzvDmX-oJ8AnrazMU-zZ5hb-u3t2ERew=366BFE3A"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the atlassian API + [DEBUG] Using Key=ATCTT3xFfGN0GsZNgOGrQSHSnxiJVi00oHlRicyM0yMNuKCBfw6qOHVcCy4Hm89GnclGb_W-1qAkxqCn5XbuyoX54bNhpK5yFKGFR7ocV6FByvL_P9Sb3tFnbUg3T3I3S_RGCBLMSN7Nsa4GJv8JEJ6bzvDmX-oJ8AnrazMU-zZ5hb-u3t2ERew=366BFE3A + [INFO] Response received: 200 OK + `, + want: []string{"ATCTT3xFfGN0GsZNgOGrQSHSnxiJVi00oHlRicyM0yMNuKCBfw6qOHVcCy4Hm89GnclGb_W-1qAkxqCn5XbuyoX54bNhpK5yFKGFR7ocV6FByvL_P9Sb3tFnbUg3T3I3S_RGCBLMSN7Nsa4GJv8JEJ6bzvDmX-oJ8AnrazMU-zZ5hb-u3t2ERew=366BFE3A"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {98651} + {AQAAABAAA ATCTT3xFfGXc59Vkq40qLX=iEOIrJRZ} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"ATCTT3xFfGXc59Vkq40qLX=iEOIrJRZ"}, }, } @@ -27,22 +47,15 @@ func TestAtlassian_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -54,6 +67,7 @@ func TestAtlassian_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/audd/audd_test.go b/pkg/detectors/audd/audd_test.go index ff38207c6..931f04773 100644 --- a/pkg/detectors/audd/audd_test.go +++ b/pkg/detectors/audd/audd_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "audd_key: 60fzzcspq2balbxn7f3hi2nvg3h07h4z" - invalidPattern = "audd_key: 60fuzcsoq2balxbN7f3hi2nvg3h07h4z" -) - func TestAudd_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAudd_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"60fzzcspq2balbxn7f3hi2nvg3h07h4z"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the audd API + [DEBUG] Using Key=60fzzcspq2balbxn7f3hi2nvg3h07h4z + [INFO] Response received: 200 OK + `, + want: []string{"60fzzcspq2balbxn7f3hi2nvg3h07h4z"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {audd} + {AQAAABAAA uv2kv0x8htfhgnugnsbys7a8oyky5ryb} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"uv2kv0x8htfhgnugnsbys7a8oyky5ryb"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the audd API + [DEBUG] Using Key=60fzzcspq2balbxn7f3hi2nvg3h07h4zY + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAudd_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAudd_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/auth0managementapitoken/auth0managementapitoken_test.go b/pkg/detectors/auth0managementapitoken/auth0managementapitoken_test.go index 897f8580d..46eee7bfc 100644 --- a/pkg/detectors/auth0managementapitoken/auth0managementapitoken_test.go +++ b/pkg/detectors/auth0managementapitoken/auth0managementapitoken_test.go @@ -9,20 +9,15 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) var ( - // TODO(kashif): Refactor the fake token generation if possible - validPattern = generateRandomString() // this has the exact token string only which can be used in want too - validDomain = "QHHPu7VPj.sI.auth0.com" - invalidPattern = ` - auth0_credentials: - apiToken: eywT2nGMZwOcbsUVBwfiRPEl8P_wnmo6XfdUoGVwxDfOSjNyqhYqFdi.KojZZOM8Ox - domain: QHHPu7VPj.sI.auth0.com - ` + // TODO: Refactor the fake token generation if possible + validPattern = generateRandomString() // this has the exact token string only which can be used in want too ) func TestAuth0ManagementApitToken_Pattern(t *testing.T) { @@ -36,13 +31,17 @@ func TestAuth0ManagementApitToken_Pattern(t *testing.T) { }{ { name: "valid pattern", - input: makeFakeTokenString(validPattern, validDomain), - want: []string{validPattern + validDomain}, + input: makeFakeTokenString(validPattern, "Truffle-security.org.auth0.com"), + want: []string{validPattern + "Truffle-security.org.auth0.com"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + auth0_credentials: + apiToken: eywT2nGMZwOcbsUVBwfiRPEl8P_wnmo6XfdUoGVwxDfOSjNyqhYqFdi.KojZZOM8Ox + domain: Truffle-security.org.auth0.com + `, + want: nil, }, } @@ -50,22 +49,15 @@ func TestAuth0ManagementApitToken_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -77,6 +69,7 @@ func TestAuth0ManagementApitToken_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} @@ -94,7 +87,7 @@ func makeFakeTokenString(token, domain string) string { return fmt.Sprintf("auth0:\n apiToken: %s \n domain: %s", token, domain) } -// generateRandomString generates exactly 2001 char string for a fake token to by pass the check in detector for testing +// generateRandomString generates exactly 2001 char string for a fake token to pass the check in detector for testing func generateRandomString() string { const length = 2001 const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" diff --git a/pkg/detectors/auth0oauth/auth0oauth_test.go b/pkg/detectors/auth0oauth/auth0oauth_test.go index e573e5c03..1f7882405 100644 --- a/pkg/detectors/auth0oauth/auth0oauth_test.go +++ b/pkg/detectors/auth0oauth/auth0oauth_test.go @@ -5,26 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - auth0_credentials file: - auth0_clientID: kYWr_tL4eYBtqIIvKfSf2-e4T9Cw1CtwE8ufoESVBB7Hi1U - secret: rXwGtKCleBsaUfpchggQEAy_yhzWnqv4_GzJivBif85bqiJi3ZA63DAauoJ2PF27fvS-MBqIYgxH0vZaL1s5314lgPDLqHXjZsY59PSew63A_L6rySqcy5J3rFcGcpdeSQ_tTx1kCXOZY_JUy - domain: 9-KhTIdSopSaMQ2v1YxdFEJN-HNgt7Mn7E8xkfQNqd51AzSGQu2yRaFauth0.com - ` - invalidPattern = ` - auth0_credentials file: - auth0_clientID: e4T9Cw1CtwE8ufoESVBB7Hi1U-e4T9Cw1CtwE8ufoESVBB7Hi1U - secret: MBqIYgxH0vZaL1s5314lgPDLqHX^ZsY59PSew63A_L6rySqcy5J3rFcGcpdeSQ_+tTx1kCXOZY_JUy-rXwGtKCleBsaUfpchggQEAy_yhzWnqv4_GzJivBif85bqiJi3ZA63DAauoJ2PF27fvS - domain: 9-KhTIdSopSaMQ2v1YxdFEJN#qd51AzSGQu2yRaFauth1.com - ` -) - func TestAuth0oAuth_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -35,14 +21,41 @@ func TestAuth0oAuth_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"kYWr_tL4eYBtqIIvKfSf2-e4T9Cw1CtwE8ufoESVBB7Hi1UrXwGtKCleBsaUfpchggQEAy_yhzWnqv4_GzJivBif85bqiJi3ZA63DAauoJ2PF27fvS-MBqIYgxH0vZaL1s5314lgPDLqHXjZsY59PSew63A_L6rySqcy5J3rFcGcpdeSQ_tTx1kCXOZY_JUy"}, + name: "valid pattern", + input: ` + # do not share these credentials + auth0_credentials file: + auth0_clientID: kYWr_tL4eYBtqIIvKfSf2-e4T9Cw1CtwE8ufoESVBB7Hi1U + secret: rXwGtKCleBsaUfpchggQEAy_yhzWnqv4_GzJivBif85bqiJi3ZA63DAauoJ2PF27fvS-MBqIYgxH0vZaL1s5314lgPDLqHXjZsY59PSew63A_L6rySqcy5J3rFcGcpdeSQ_tTx1kCXOZY_JUy + domain: 9-KhTIdSopSaMQ2v1YxdFEJN-HNgt7Mn7E8xkfQNqd51AzSGQu2yRaFauth0.com + `, + want: []string{"kYWr_tL4eYBtqIIvKfSf2-e4T9Cw1CtwE8ufoESVBB7Hi1UrXwGtKCleBsaUfpchggQEAy_yhzWnqv4_GzJivBif85bqiJi3ZA63DAauoJ2PF27fvS-MBqIYgxH0vZaL1s5314lgPDLqHXjZsY59PSew63A_L6rySqcy5J3rFcGcpdeSQ_tTx1kCXOZY_JUy"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {auth0 rP_yIAV6HD3Oe4zr6KawRXGbq6UCWbeC1kbjQkVhqG4vcLCc2} + {AQAAABAAA 1PMNVllg_WHl2OGdPLSs73Z1NHjQ85nafV2qqKbQivoqEz4RSo6MFBoNxF-XqFKjEyt6WJfZvAslDPrwY-B-MLsN13rgxRrAiFw9d8Rl1e0uC0FCNDC5EALR9kq7cs4Atz_Dv4r5YT8drkV1_T5HMjH8SJb2B-jD} + {kXFuauth0.com} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"rP_yIAV6HD3Oe4zr6KawRXGbq6UCWbeC1kbjQkVhqG4vcLCc21PMNVllg_WHl2OGdPLSs73Z1NHjQ85nafV2qqKbQivoqEz4RSo6MFBoNxF-XqFKjEyt6WJfZvAslDPrwY-B-MLsN13rgxRrAiFw9d8Rl1e0uC0FCNDC5EALR9kq7cs4Atz_Dv4r5YT8drkV1_T5HMjH8SJb2B-jD"}, + }, + { + name: "invalid pattern", + input: ` + # do not share these credentials + auth0_credentials file: + auth0_clientID: e4T9Cw1CtwE8ufoESVBB7Hi1U-e4T9Cw1CtwE8ufoESVBB7Hi1U + secret: MBqIYgxH0vZaL1s5314lgPDLqHX^ZsY59PSew63A_L6rySqcy5J3rFcGcpdeSQ_+tTx1kCXOZY_JUy-rXwGtKCleBsaUfpchggQEAy_yhzWnqv4_GzJivBif85bqiJi3ZA63DAauoJ2PF27fvS + domain: 9-KhTIdSopSaMQ2v1YxdFEJN#qd51AzSGQu2yRaFauth1.com + `, + want: nil, }, } @@ -50,22 +63,15 @@ func TestAuth0oAuth_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -77,6 +83,7 @@ func TestAuth0oAuth_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/autodesk/autodesk_test.go b/pkg/detectors/autodesk/autodesk_test.go index cf469f817..85be13293 100644 --- a/pkg/detectors/autodesk/autodesk_test.go +++ b/pkg/detectors/autodesk/autodesk_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "autodesk_key: 2j8Rl67MjoMruYfyIBgGzy2pxcxIQfet / autodesk_secret rHfzZhsSRruLM3Fn" - invalidPattern = "autodesk: 2mm8Rl67MjoMruYfyIBg5#zy2pxcxIQfet / autodesk_secret RHGklpa" -) - func TestAutoDesk_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,38 @@ func TestAutoDesk_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"2j8Rl67MjoMruYfyIBgGzy2pxcxIQfetrHfzZhsSRruLM3Fn"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using autodesk Key=2j8Rl67MjoMruYfyIBgGzy2pxcxIQfet + [DEBUG] Using autodesk Secret=rHfzZhsSRruLM3Fn + [INFO] Response received: 200 OK + `, + want: []string{"2j8Rl67MjoMruYfyIBgGzy2pxcxIQfetrHfzZhsSRruLM3Fn"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {autodesk 0xjHuuRZc8n0YS6MGd8e3OakAySlK27q} + {autodesk AQAAABAAA 0TvJm15Ew8KADWTN} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"0xjHuuRZc8n0YS6MGd8e3OakAySlK27q0TvJm15Ew8KADWTN"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the API + [DEBUG] Using autodesk Key=2mm8Rl67MjoMruYfyIBg5#zy2pxcxIQfet + [DEBUG] Using autodesk Secret=RHGklpa + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +60,15 @@ func TestAutoDesk_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +80,7 @@ func TestAutoDesk_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/autoklose/autoklose_test.go b/pkg/detectors/autoklose/autoklose_test.go index 4ed460f78..6553cca91 100644 --- a/pkg/detectors/autoklose/autoklose_test.go +++ b/pkg/detectors/autoklose/autoklose_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "autoklose credentials: KRXaU9GK3f9yHG1FS-mbwhsIXdW22epH" - invalidPattern = "autoklose credentials: KRXaU9GK3f[yHG1FS$]bwhsIXdW22epH" -) - func TestAutoKlose_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAutoKlose_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"KRXaU9GK3f9yHG1FS-mbwhsIXdW22epH"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the autoklose API + [DEBUG] Using Key=KRXaU9GK3f9yHG1FS-mbwhsIXdW22epH + [INFO] Response received: 200 OK + `, + want: []string{"KRXaU9GK3f9yHG1FS-mbwhsIXdW22epH"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {autoklose} + {AQAAABAAA Z6Q4KENlmgGJT-M-BLoup9Dmyj2YVC-I} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"Z6Q4KENlmgGJT-M-BLoup9Dmyj2YVC-I"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the autoklose API + [DEBUG] Using Key=KRXaU9GK3f[yHG1FS$]bwhsIXdW22epH + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAutoKlose_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAutoKlose_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/autopilot/autopilot_test.go b/pkg/detectors/autopilot/autopilot_test.go index dd5a5f67c..eee6f1801 100644 --- a/pkg/detectors/autopilot/autopilot_test.go +++ b/pkg/detectors/autopilot/autopilot_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "autopilot credentials: 0fd87cfb1ca6c38c5f1ae5be7b0e395e" - invalidPattern = "autopilot credentials: KRXaU9GK3f[yHG1FS$]bwhsIXdW22epH" -) - func TestAutoPilot_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAutoPilot_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"0fd87cfb1ca6c38c5f1ae5be7b0e395e"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the autopilot API + [DEBUG] Using Key=0fd87cfb1ca6c38c5f1ae5be7b0e395e + [INFO] Response received: 200 OK + `, + want: []string{"0fd87cfb1ca6c38c5f1ae5be7b0e395e"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {autopilot} + {AQAAABAAA 60aa8204a2b1dec8af7de45737fed7be} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"60aa8204a2b1dec8af7de45737fed7be"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the autopilot API + [DEBUG] Using Key=KRXaU9GK3f[yHG1FS$]bwhsIXdW22epH + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAutoPilot_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAutoPilot_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/avazapersonalaccesstoken/avazapersonalaccesstoken_test.go b/pkg/detectors/avazapersonalaccesstoken/avazapersonalaccesstoken_test.go index 7ef07b611..2c143c40a 100644 --- a/pkg/detectors/avazapersonalaccesstoken/avazapersonalaccesstoken_test.go +++ b/pkg/detectors/avazapersonalaccesstoken/avazapersonalaccesstoken_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "avaza credentials: 01818612883613176996369293-f113ceb9cf4fa63dc367ab4815b0e1edf890745f" - invalidPattern = "avaza credentials: 01818612883613176996369293-fzz3ceb0mf4fp63dh367xb4815b0e1edf890745f" -) - func TestAvazaPersonalAccessToken_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAvazaPersonalAccessToken_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"01818612883613176996369293-f113ceb9cf4fa63dc367ab4815b0e1edf890745f"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the avaza API + [DEBUG] Using Key=01818612883613176996369293-f113ceb9cf4fa63dc367ab4815b0e1edf890745f + [INFO] Response received: 200 OK + `, + want: []string{"01818612883613176996369293-f113ceb9cf4fa63dc367ab4815b0e1edf890745f"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {avaza} + {AQAAABAAA 6605785514902-06e236581be50b798459a53fcb7609032bf813f7} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"6605785514902-06e236581be50b798459a53fcb7609032bf813f7"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the avaza API + [DEBUG] Using Key=01818612883613176996369293-fzz3ceb0mf4fp63dh367xb4815b0e1edf890745f + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAvazaPersonalAccessToken_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAvazaPersonalAccessToken_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aviationstack/aviationstack_test.go b/pkg/detectors/aviationstack/aviationstack_test.go index c76924c9a..0a1dbdea2 100644 --- a/pkg/detectors/aviationstack/aviationstack_test.go +++ b/pkg/detectors/aviationstack/aviationstack_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "aviationstack credentials: osh0kjinsc2atoaqntoy1hdjppg54449" - invalidPattern = "aviationstack credentials: OSh0lMjinsc2atoaqnto[]1hdjppg5449" -) - func TestAviationStack_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAviationStack_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"osh0kjinsc2atoaqntoy1hdjppg54449"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the aviationstack API + [DEBUG] Using Key=osh0kjinsc2atoaqntoy1hdjppg54449 + [INFO] Response received: 200 OK + `, + want: []string{"osh0kjinsc2atoaqntoy1hdjppg54449"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {aviationstack} + {AQAAABAAA 464r3ib5xzipgd36zdzpvm09p00juu0b} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"464r3ib5xzipgd36zdzpvm09p00juu0b"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the aviationstack API + [DEBUG] Using Key=OSh0lMjinsc2atoaqnto[]1hdjppg5449 + [ERROR] Response received: 400 BadRequest + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAviationStack_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAviationStack_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aws/access_keys/accesskey_test.go b/pkg/detectors/aws/access_keys/accesskey_test.go index 96c44b2fb..2ecaae3e1 100644 --- a/pkg/detectors/aws/access_keys/accesskey_test.go +++ b/pkg/detectors/aws/access_keys/accesskey_test.go @@ -5,26 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - aws credentials{ - id: ABIAS9L8MS5IPHTZPPUQ - secret: .v2QPKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63; - } - ` - invalidPattern = ` - aws credentials{ - id: AKIAs9L8MS5iPHTZPPUQ - secret: $YenOG.PKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63; - } - ` -) - func TestAWS_Pattern(t *testing.T) { d := scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -35,14 +21,38 @@ func TestAWS_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"ABIAS9L8MS5IPHTZPPUQ:v2QPKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63"}, + name: "valid pattern", + input: ` + aws credentials{ + id: ABIAS9L8MS5IPHTZPPUQ + secret: .v2QPKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63; + } + `, + want: []string{"ABIAS9L8MS5IPHTZPPUQ:v2QPKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {AKIAWGXZ9OPDOWUJMZGI} + {AQAAABAAA .v2QPKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63;} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"AKIAWGXZ9OPDOWUJMZGI:v2QPKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63"}, + }, + { + name: "invalid pattern", + input: ` + aws credentials{ + id: AKIAs9L8MS5iPHTZPPUQ + secret: $YenOG.PKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63; + } + `, + want: nil, }, } @@ -50,22 +60,15 @@ func TestAWS_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -77,6 +80,7 @@ func TestAWS_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aws/session_keys/sessionkeys_test.go b/pkg/detectors/aws/session_keys/sessionkeys_test.go index 39c5ba64e..c1f0690cc 100644 --- a/pkg/detectors/aws/session_keys/sessionkeys_test.go +++ b/pkg/detectors/aws/session_keys/sessionkeys_test.go @@ -5,27 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - aws credentials{ - id: ASIABBKK02W42Q3IPSPG - secret: fkhIiUwQY32Zu9e4a86g9r3WpTzfE1aXljVcgn8O - session: aSqfp/GTZbJP+tXPNCZ9GoveoM0vgxtlYXdzPQ2uYNMPPgUkt0VT7SoTLasAo7iVqWWREOUC6DEenlcgDEKyzIEgQW5Ju/b9K/Z176uD2HJYCfq/lyowHtt5PvJi7LRuf/urSorGbTcqNUvPi42YP1Ps/4F6He9hQA1io3EAGBC3ICGHXWf2IlvFoTNUyPTqhjnPEKMWZ42jblqNAdD7hLpzNXmmGhdLCjy99XK8+gjHdZHkOeD/FIjRPRZ7Jl0tdwdqFEwzRVCzL2uelMVMd3UaZ+d4I4Kf+J464piO//jxx48Fs/mG3zr5ba9m2S+6gvUZJq4j+0uJ+jf6cG/x2G9XSybqYQRwvxfNquKB4TcKiGVH5+ZbJT4ASkARadwoSPMGfvMPje+X2zAziSzXfsxYfIQKf6iJ9p7VavlDGi+Acr4kwFXW5IfQs4uGk6AVQFsoZK3o1hhLOkuOwWQEWhDQGNLXwJbFqXfELOnUQvM0Z5NUm46bjAAi4g+X9gLPNR/KjzXuuTTaWYrQEjXLb7PxS0sIttAb1w+sTXXtc1kDIsABC6KcsyGlEwji5sLkbkUa= - } - ` - invalidPattern = ` - aws credentials{ - id: ASIABBKK02W42Q3IPSPG - secret: $YenOG.PKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63; - } - ` -) - func TestAWSSessionKey_Pattern(t *testing.T) { d := New() ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -36,14 +21,40 @@ func TestAWSSessionKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"ASIABBKK02W42Q3IPSPG:fkhIiUwQY32Zu9e4a86g9r3WpTzfE1aXljVcgn8O:aSqfp/GTZbJP+tXPNCZ9GoveoM0vgxtlYXdzPQ2uYNMPPgUkt0VT7SoTLasAo7iVqWWREOUC6DEenlcgDEKyzIEgQW5Ju/b9K/Z176uD2HJYCfq/lyowHtt5PvJi7LRuf/urSorGbTcqNUvPi42YP1Ps/4F6He9hQA1io3EAGBC3ICGHXWf2IlvFoTNUyPTqhjnPEKMWZ42jblqNAdD7hLpzNXmmGhdLCjy99XK8+gjHdZHkOeD/FIjRPRZ7Jl0tdwdqFEwzRVCzL2uelMVMd3UaZ+d4I4Kf+J464piO//jxx48Fs/mG3zr5ba9m2S+6gvUZJq4j+0uJ+jf6cG/x2G9XSybqYQRwvxfNquKB4TcKiGVH5+ZbJT4ASkARadwoSPMGfvMPje+X2zAziSzXfsxYfIQKf6iJ9p7VavlDGi+Acr4kwFXW5IfQs4uGk6AVQFsoZK3o1hhLOkuOwWQEWhDQGNLXwJbFqXfELOnUQvM0Z5NUm46bjAAi4g+X9gLPNR/KjzXuuTTaWYrQEjXLb7PxS0sIttAb1w+sTXXtc1kDIsABC6KcsyGlEwji5sLkbkUa="}, + name: "valid pattern", + input: ` + aws credentials{ + id: ASIABBKK02W42Q3IPSPG + secret: fkhIiUwQY32Zu9e4a86g9r3WpTzfE1aXljVcgn8O + session: aSqfp/GTZbJP+tXPNCZ9GoveoM0vgxtlYXdzPQ2uYNMPPgUkt0VT7SoTLasAo7iVqWWREOUC6DEenlcgDEKyzIEgQW5Ju/b9K/Z176uD2HJYCfq/lyowHtt5PvJi7LRuf/urSorGbTcqNUvPi42YP1Ps/4F6He9hQA1io3EAGBC3ICGHXWf2IlvFoTNUyPTqhjnPEKMWZ42jblqNAdD7hLpzNXmmGhdLCjy99XK8+gjHdZHkOeD/FIjRPRZ7Jl0tdwdqFEwzRVCzL2uelMVMd3UaZ+d4I4Kf+J464piO//jxx48Fs/mG3zr5ba9m2S+6gvUZJq4j+0uJ+jf6cG/x2G9XSybqYQRwvxfNquKB4TcKiGVH5+ZbJT4ASkARadwoSPMGfvMPje+X2zAziSzXfsxYfIQKf6iJ9p7VavlDGi+Acr4kwFXW5IfQs4uGk6AVQFsoZK3o1hhLOkuOwWQEWhDQGNLXwJbFqXfELOnUQvM0Z5NUm46bjAAi4g+X9gLPNR/KjzXuuTTaWYrQEjXLb7PxS0sIttAb1w+sTXXtc1kDIsABC6KcsyGlEwji5sLkbkUa= + } + `, + want: []string{"ASIABBKK02W42Q3IPSPG:fkhIiUwQY32Zu9e4a86g9r3WpTzfE1aXljVcgn8O:aSqfp/GTZbJP+tXPNCZ9GoveoM0vgxtlYXdzPQ2uYNMPPgUkt0VT7SoTLasAo7iVqWWREOUC6DEenlcgDEKyzIEgQW5Ju/b9K/Z176uD2HJYCfq/lyowHtt5PvJi7LRuf/urSorGbTcqNUvPi42YP1Ps/4F6He9hQA1io3EAGBC3ICGHXWf2IlvFoTNUyPTqhjnPEKMWZ42jblqNAdD7hLpzNXmmGhdLCjy99XK8+gjHdZHkOeD/FIjRPRZ7Jl0tdwdqFEwzRVCzL2uelMVMd3UaZ+d4I4Kf+J464piO//jxx48Fs/mG3zr5ba9m2S+6gvUZJq4j+0uJ+jf6cG/x2G9XSybqYQRwvxfNquKB4TcKiGVH5+ZbJT4ASkARadwoSPMGfvMPje+X2zAziSzXfsxYfIQKf6iJ9p7VavlDGi+Acr4kwFXW5IfQs4uGk6AVQFsoZK3o1hhLOkuOwWQEWhDQGNLXwJbFqXfELOnUQvM0Z5NUm46bjAAi4g+X9gLPNR/KjzXuuTTaWYrQEjXLb7PxS0sIttAb1w+sTXXtc1kDIsABC6KcsyGlEwji5sLkbkUa="}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {ASIABBKK02W42Q3IPSPG} + {AQAAABAAA fkhIiUwQY32Zu9e4a86g9r3WpTzfE1aXljVcgn8O} + {AQAAABAAA aSqfp/GTZbJP+tXPNCZ9GoveoM0vgxtlYXdzPQ2uYNMPPgUkt0VT7SoTLasAo7iVqWWREOUC6DEenlcgDEKyzIEgQW5Ju/b9K/Z176uD2HJYCfq/lyowHtt5PvJi7LRuf/urSorGbTcqNUvPi42YP1Ps/4F6He9hQA1io3EAGBC3ICGHXWf2IlvFoTNUyPTqhjnPEKMWZ42jblqNAdD7hLpzNXmmGhdLCjy99XK8+gjHdZHkOeD/FIjRPRZ7Jl0tdwdqFEwzRVCzL2uelMVMd3UaZ+d4I4Kf+J464piO//jxx48Fs/mG3zr5ba9m2S+6gvUZJq4j+0uJ+jf6cG/x2G9XSybqYQRwvxfNquKB4TcKiGVH5+ZbJT4ASkARadwoSPMGfvMPje+X2zAziSzXfsxYfIQKf6iJ9p7VavlDGi+Acr4kwFXW5IfQs4uGk6AVQFsoZK3o1hhLOkuOwWQEWhDQGNLXwJbFqXfELOnUQvM0Z5NUm46bjAAi4g+X9gLPNR/KjzXuuTTaWYrQEjXLb7PxS0sIttAb1w+sTXXtc1kDIsABC6KcsyGlEwji5sLkbkUa=} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"ASIABBKK02W42Q3IPSPG:fkhIiUwQY32Zu9e4a86g9r3WpTzfE1aXljVcgn8O:aSqfp/GTZbJP+tXPNCZ9GoveoM0vgxtlYXdzPQ2uYNMPPgUkt0VT7SoTLasAo7iVqWWREOUC6DEenlcgDEKyzIEgQW5Ju/b9K/Z176uD2HJYCfq/lyowHtt5PvJi7LRuf/urSorGbTcqNUvPi42YP1Ps/4F6He9hQA1io3EAGBC3ICGHXWf2IlvFoTNUyPTqhjnPEKMWZ42jblqNAdD7hLpzNXmmGhdLCjy99XK8+gjHdZHkOeD/FIjRPRZ7Jl0tdwdqFEwzRVCzL2uelMVMd3UaZ+d4I4Kf+J464piO//jxx48Fs/mG3zr5ba9m2S+6gvUZJq4j+0uJ+jf6cG/x2G9XSybqYQRwvxfNquKB4TcKiGVH5+ZbJT4ASkARadwoSPMGfvMPje+X2zAziSzXfsxYfIQKf6iJ9p7VavlDGi+Acr4kwFXW5IfQs4uGk6AVQFsoZK3o1hhLOkuOwWQEWhDQGNLXwJbFqXfELOnUQvM0Z5NUm46bjAAi4g+X9gLPNR/KjzXuuTTaWYrQEjXLb7PxS0sIttAb1w+sTXXtc1kDIsABC6KcsyGlEwji5sLkbkUa="}, + }, + { + name: "invalid pattern", + input: ` + aws credentials{ + id: ASIABBKK02W42Q3IPSPG + secret: $YenOG.PKHl7LcdVYsjaR4LgQiZ1zw3MAnMyiondXC63; + } + `, + want: nil, }, } @@ -51,22 +62,15 @@ func TestAWSSessionKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -78,6 +82,7 @@ func TestAWSSessionKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/axonaut/axonaut_test.go b/pkg/detectors/axonaut/axonaut_test.go index fdf924afc..522d5ae06 100644 --- a/pkg/detectors/axonaut/axonaut_test.go +++ b/pkg/detectors/axonaut/axonaut_test.go @@ -5,24 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - axonaut credentials{ - key: 4ve4aj6v38uiadaq9hcgpupp2b3lh2k8 - } - ` - invalidPattern = ` - axonaut credentials{ - key: ASIABBKK02W42Q3IPSPG - } - ` -) - func TestAxonaut_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,14 +21,36 @@ func TestAxonaut_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"4ve4aj6v38uiadaq9hcgpupp2b3lh2k8"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the axonaut API + [DEBUG] Using Key=4ve4aj6v38uiadaq9hcgpupp2b3lh2k8 + [INFO] Response received: 200 OK + `, + want: []string{"4ve4aj6v38uiadaq9hcgpupp2b3lh2k8"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {axonaut} + {AQAAABAAA m7mnuk7p3buc87b2ok29e7ykp2xqkkx0} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"m7mnuk7p3buc87b2ok29e7ykp2xqkkx0"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the axonaut API + [DEBUG] Using Key=ASIABBKK02W42Q3IPSPG + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -48,22 +58,15 @@ func TestAxonaut_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +78,7 @@ func TestAxonaut_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/aylien/aylien_test.go b/pkg/detectors/aylien/aylien_test.go index 5f01ae03b..14cc14bae 100644 --- a/pkg/detectors/aylien/aylien_test.go +++ b/pkg/detectors/aylien/aylien_test.go @@ -5,24 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - aylien credentials: - aylien key: cr479du2l9pkmhar8gw5hufofvwp86q9 - aylien id: y3ejw028 - ` - invalidPattern = ` - aylien credentials: - aylien key: cr4U9du2l9pkmhar8gw5hufofvWp86q9 - aylien id: y3ejwA8 - ` -) - func TestAylien_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,14 +21,40 @@ func TestAylien_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"cr479du2l9pkmhar8gw5hufofvwp86q9y3ejw028"}, + name: "valid pattern", + input: ` + # do not share these credentials + aylien credentials: + aylien key: cr479du2l9pkmhar8gw5hufofvwp86q9 + aylien id: y3ejw028 + # valid till Dec 2025 + `, + want: []string{"cr479du2l9pkmhar8gw5hufofvwp86q9y3ejw028"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {aylien wmxv7ckn} + {aylien AQAAABAAA i09t8rb5r7otvq8sdrfjunakcso157mh} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"i09t8rb5r7otvq8sdrfjunakcso157mhwmxv7ckn"}, + }, + { + name: "invalid pattern", + input: ` + # do not share these credentials + aylien credentials: + aylien key: cr4U9du2l9pkmhar8gw5hufofvWp86q9 + aylien id: y3ejwA8 + # valid till Dec 2025 + `, + want: nil, }, } @@ -48,22 +62,15 @@ func TestAylien_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +82,7 @@ func TestAylien_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/ayrshare/ayrshare_test.go b/pkg/detectors/ayrshare/ayrshare_test.go index 9eb55166f..e26c71262 100644 --- a/pkg/detectors/ayrshare/ayrshare_test.go +++ b/pkg/detectors/ayrshare/ayrshare_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "ayrshare credentials: 2FTJTA1C-BXO0DV4J-HGTP9E62-QHQSILY1" - invalidPattern = "ayrshare credentials: KRXaU9GK3f[yHG1FS$]bwhsIXdW22epH" -) - func TestAyrShare_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -25,14 +21,36 @@ func TestAyrShare_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"2FTJTA1C-BXO0DV4J-HGTP9E62-QHQSILY1"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the ayrshare API + [DEBUG] Using Key=2FTJTA1C-BXO0DV4J-HGTP9E62-QHQSILY1 + [INFO] Response received: 200 OK + `, + want: []string{"2FTJTA1C-BXO0DV4J-HGTP9E62-QHQSILY1"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {ayrshare} + {AQAAABAAA I1WPQLUQ-NCNHEI13-1MF4HJZQ-EEDDVZYO} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"I1WPQLUQ-NCNHEI13-1MF4HJZQ-EEDDVZYO"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the ayrshare API + [DEBUG] Using Key=KRXaU9GK3f[yHG1FS$]bwhsIXdW22epH + [ERROR] Response received: 401 UnAuthorized + `, + want: nil, }, } @@ -40,22 +58,15 @@ func TestAyrShare_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +78,7 @@ func TestAyrShare_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azure_batch/azurebatch_test.go b/pkg/detectors/azure_batch/azurebatch_test.go index ae79b2016..058473f2f 100644 --- a/pkg/detectors/azure_batch/azurebatch_test.go +++ b/pkg/detectors/azure_batch/azurebatch_test.go @@ -5,24 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - azure batch: - url: https://JrxlYxT+0hW.YSA.batch.azure.com - secret: BXIMbhBlC3=5hIbqCEKvq7opaV2ZfO0XWbcnasZmPm/AJfQqdcnt/AVmKkJ8Qw80Zc1rQDaw+2Ytxc1hDq1m/LB0 - ` - invalidPattern = ` - azure batch: - url: http://invalid.this.batch.azure.com - secret: BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/AVmKkJ8Qw80Zc1rQDaw+2Ytxc1hDq1m/ - ` -) - func TestAzureBatch_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,14 +21,38 @@ func TestAzureBatch_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"https://JrxlYxT+0hW.YSA.batch.azure.comBXIMbhBlC3=5hIbqCEKvq7opaV2ZfO0XWbcnasZmPm/AJfQqdcnt/AVmKkJ8Qw80Zc1rQDaw+2Ytxc1hDq1m/LB0"}, + name: "valid pattern", + input: ` + [INFO] Sending request to the ayrshare API + [DEBUG] Using Secret = BXIMbhBlC3=5hIbqCEKvq7opaV2ZfO0XWbcnasZmPm/AJfQqdcnt/AVmKkJ8Qw80Zc1rQDaw+2Ytxc1hDq1m/LB0 + [INFO] https://JrxlYxT+0hW.YSA.batch.azure.com + [INFO] Response received: 200 OK + `, + want: []string{"https://JrxlYxT+0hW.YSA.batch.azure.comBXIMbhBlC3=5hIbqCEKvq7opaV2ZfO0XWbcnasZmPm/AJfQqdcnt/AVmKkJ8Qw80Zc1rQDaw+2Ytxc1hDq1m/LB0"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {https://pb0bik2a59qznkh87pdd6twjlgzpmxz.pfv9bpr2hujs.batch.azure.com} + {AQAAABAAA XJc2nGZvqPAXYfHxsiwUDBA4ynHzGc9nQl1Ih16lk19=2+qqeJUDp5eBxWVrE0LQYlnbeu/orbEtblFL218S4Wko} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"https://pb0bik2a59qznkh87pdd6twjlgzpmxz.pfv9bpr2hujs.batch.azure.comXJc2nGZvqPAXYfHxsiwUDBA4ynHzGc9nQl1Ih16lk19=2+qqeJUDp5eBxWVrE0LQYlnbeu/orbEtblFL218S4Wko"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] Sending request to the ayrshare API + [DEBUG] Using Secret=BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/AVmKkJ8Qw80Zc1rQDaw+2Ytxc1hDq1m/ + [INFO] http://invalid.this.batch.azure.com + [INFO] Response received: 200 OK + `, + want: nil, }, } @@ -48,22 +60,15 @@ func TestAzureBatch_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +80,7 @@ func TestAzureBatch_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azure_cosmosdb/azure_cosmosdb.go b/pkg/detectors/azure_cosmosdb/azure_cosmosdb.go index 9c3fc9b5a..906a86119 100644 --- a/pkg/detectors/azure_cosmosdb/azure_cosmosdb.go +++ b/pkg/detectors/azure_cosmosdb/azure_cosmosdb.go @@ -27,7 +27,7 @@ type Scanner struct { var ( defaultClient = common.SaneHttpClient() - dbKeyPattern = regexp.MustCompile(detectors.PrefixRegex([]string{"azure", "cosmos"}) + `([A-Za-z0-9]{86}==)`) + dbKeyPattern = regexp.MustCompile(`([A-Za-z0-9]{86}==)`) // account name can contain only lowercase letters, numbers and the `-` character, must be between 3 and 44 characters long. accountUrlPattern = regexp.MustCompile(`([a-z0-9-]{3,44}\.(?:documents|table\.cosmos)\.azure\.com)`) diff --git a/pkg/detectors/azure_cosmosdb/azure_cosmosdb_test.go b/pkg/detectors/azure_cosmosdb/azure_cosmosdb_test.go index 714f047e3..c4c1740a5 100644 --- a/pkg/detectors/azure_cosmosdb/azure_cosmosdb_test.go +++ b/pkg/detectors/azure_cosmosdb/azure_cosmosdb_test.go @@ -2,10 +2,10 @@ package azure_cosmosdb import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -29,7 +29,21 @@ func TestCosmosDB_Pattern(t *testing.T) { // config cosmosKey: FakeeP35zYGPXaEUfakeU7S8kcOY7NI7id8ddbHfakeAifake8Bbql1mXhMF2t0wQ0FAKEPQrwZZACDb3msoAg== https://trufflesecurity-fake.documents.azure.com:443`, - want: []string{fmt.Sprintf("key: %s account_url: %s", "FakeeP35zYGPXaEUfakeU7S8kcOY7NI7id8ddbHfakeAifake8Bbql1mXhMF2t0wQ0FAKEPQrwZZACDb3msoAg==", "trufflesecurity-fake.documents.azure.com")}, + want: []string{"key: FakeeP35zYGPXaEUfakeU7S8kcOY7NI7id8ddbHfakeAifake8Bbql1mXhMF2t0wQ0FAKEPQrwZZACDb3msoAg== account_url: trufflesecurity-fake.documents.azure.com"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {jc0338vpo7bd3rn99vu2trdbo.table.cosmos.azure.com} + {AQAAABAAA tiHd2l1I3MptBj4s1zomhyIAuCJmR1bzxvGluBVW2k0JJ7Z6vmybKYiM7OY5HtDkvLVxyDD2ACW0GW2fug0cET==} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"key: tiHd2l1I3MptBj4s1zomhyIAuCJmR1bzxvGluBVW2k0JJ7Z6vmybKYiM7OY5HtDkvLVxyDD2ACW0GW2fug0cET== account_url: jc0338vpo7bd3rn99vu2trdbo.table.cosmos.azure.com"}, }, { name: "valid table db pattern", @@ -40,7 +54,7 @@ func TestCosmosDB_Pattern(t *testing.T) { // config cosmosKey: FakeeP35zYGPXaEUfakeU7S8kcOY7NI7id8ddbHfakeAifake8Bbql1mXhMF2t0wQ0FAKEPQrwZZACDb3msoAg== https://trufflesecurity-fake.table.cosmos.azure.com:443`, - want: []string{fmt.Sprintf("key: %s account_url: %s", "FakeeP35zYGPXaEUfakeU7S8kcOY7NI7id8ddbHfakeAifake8Bbql1mXhMF2t0wQ0FAKEPQrwZZACDb3msoAg==", "trufflesecurity-fake.table.cosmos.azure.com")}, + want: []string{"key: FakeeP35zYGPXaEUfakeU7S8kcOY7NI7id8ddbHfakeAifake8Bbql1mXhMF2t0wQ0FAKEPQrwZZACDb3msoAg== account_url: trufflesecurity-fake.table.cosmos.azure.com"}, }, { name: "invalid pattern", @@ -55,22 +69,15 @@ func TestCosmosDB_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -82,6 +89,7 @@ func TestCosmosDB_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azure_entra/refreshtoken/refreshtoken_test.go b/pkg/detectors/azure_entra/refreshtoken/refreshtoken_test.go index aa7c1d258..ba3e52387 100644 --- a/pkg/detectors/azure_entra/refreshtoken/refreshtoken_test.go +++ b/pkg/detectors/azure_entra/refreshtoken/refreshtoken_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -27,42 +28,42 @@ func TestRefreshToken_Pattern(t *testing.T) { { name: "valid - token+client+tenant", input: ` -{ - "tokenType": "Bearer", - "expiresIn": 4742, - "expiresOn": "2024-06-07 09:09:22.294640", - "resource": "https://graph.windows.net", - "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", - "refreshToken": "0.AUUAMe_N-B6jSkuT5F9XHpElWlj2JcxuFFnRLm_3awiSnuJQsa1.AgABAwEAAADnfolhJpSnRYB1SVj-Hgd8Agrf-wUA9P9oElBtlKe8a-5_1t2eEmBef50SCv8exOOrgjUFMLtPQj_XH1rq3Onj2dCFQaHzhm7DfoOxj5LH4kR9jPIbPf2yRI0CgxFLEGMf0biO9LxmvVwb_NKTScIc_MK4eBsXG-En_e3vaIJS5t-ghSvPAKzl3pxiYVvBdP1i_nUHPl4dsCkk9SKCexWnhi4tg9xVVIi-MIkGDJxThmuKfAko1VHMgx-tsHRKgPoXlJi51uNO0KQQUxnDnjiWmLapCe3hVtjfoINBlb3CpiHkfW5G9dzF4cmFOQJQG9RdW-CU6t4VmlamK9gSbNYfyd7fWr7Ebv9Bo06eWEwEBpQmJONJERNScnqMs5Ztba9kUHchXqJd9wZMH-NtWejuR92IqMmPoaY4DP52Yodu2hWZPv0pFEFsthPJ3YpViOaJnCoSQ7ba-qzVr8TnvFlkI8EfFKNbl47_WncwKXDrPk2FlZwG4ywX7s0dXYvXDJ-rMQHsDcJDMABQXrxaU0Z7ozCk_ftVgBQocWZHAkzBtWZNw9dS4ltux0GeAYekUjzE7UYrPw41DLWOLrr7V-kx5sZ6h66iiTi-zdsJ28LnRIX4aZ6IC7jxIG0FK-roPldOEjy0XJ-V6QmyjkEYT3PK23vUTHIz3EQ8JqGNJMJO5mWwbedlIl2xq-0CczybkR2MJgr4UAQKUBFMYuUYGWrVygte9d48usQ6-MhAavmkyZb5Mo_PeMnnNef-cl6c8RUzMAOpeiumFEG-gTzyDgaoM1eFjtYKTz0mr-0lPfrEavE4LfGXh87oDb0lNrbbkMNhAXjz2rJW8ex1REfeBH4oit0WeMWH-sIvpT3H8jsYIawfPp7rBN9z_TMX9AUbqROEY2Nv1jSJsXCX0sjLRweYiQnl-hHFfLcWwFIFjMfs7eOKSiOBKB3ZqjQw_A8OVDxhAQJybiVgW8U41IAjXGX0DNilrmE0PhDAqs5jQIBSO66G05yJj1RY3b2z8cYMG1lKAZ10IIDfo8f3FU-_m-w6zNVVkNZko89bX8tA91EjXpoUvmnPZKT84Qx9KvtRM561ABVEYnE152821Xy0HeObVue6M5WlF0puvqk1HnkfAUDxMk6qO1Xy7o0myTIV1R2yxFPpQX_pwCRB1IutSqz0s6E1XyfbRyv8TKxjX3_tGgvUy8KrZFeYJ9pRFsKIN_AJ9_a2GMG6h1b9aCIaA7jGlOkYlC-4LnhqoKxs4RpJJIpWWN6wZstGmIACwJS4", - "familyName": "Doe", - "givenName": "John", - "identityProvider": "live.com", - "tenantId": "16515984-9303-47f6-a59f-917611c8cb2b", - "userId": "john.doe@outlook.com", - "isUserIdDisplayable": true, - "isMRRT": true, - "_clientId": "1b730954-1685-4b74-9bfd-dac224a7b894", - "_authority": "https://login.microsoftonline.com/16515984-9303-47f6-a59f-917611c8cb2b" -}`, + { + "tokenType": "Bearer", + "expiresIn": 4742, + "expiresOn": "2024-06-07 09:09:22.294640", + "resource": "https://graph.windows.net", + "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", + "refreshToken": "0.AUUAMe_N-B6jSkuT5F9XHpElWlj2JcxuFFnRLm_3awiSnuJQsa1.AgABAwEAAADnfolhJpSnRYB1SVj-Hgd8Agrf-wUA9P9oElBtlKe8a-5_1t2eEmBef50SCv8exOOrgjUFMLtPQj_XH1rq3Onj2dCFQaHzhm7DfoOxj5LH4kR9jPIbPf2yRI0CgxFLEGMf0biO9LxmvVwb_NKTScIc_MK4eBsXG-En_e3vaIJS5t-ghSvPAKzl3pxiYVvBdP1i_nUHPl4dsCkk9SKCexWnhi4tg9xVVIi-MIkGDJxThmuKfAko1VHMgx-tsHRKgPoXlJi51uNO0KQQUxnDnjiWmLapCe3hVtjfoINBlb3CpiHkfW5G9dzF4cmFOQJQG9RdW-CU6t4VmlamK9gSbNYfyd7fWr7Ebv9Bo06eWEwEBpQmJONJERNScnqMs5Ztba9kUHchXqJd9wZMH-NtWejuR92IqMmPoaY4DP52Yodu2hWZPv0pFEFsthPJ3YpViOaJnCoSQ7ba-qzVr8TnvFlkI8EfFKNbl47_WncwKXDrPk2FlZwG4ywX7s0dXYvXDJ-rMQHsDcJDMABQXrxaU0Z7ozCk_ftVgBQocWZHAkzBtWZNw9dS4ltux0GeAYekUjzE7UYrPw41DLWOLrr7V-kx5sZ6h66iiTi-zdsJ28LnRIX4aZ6IC7jxIG0FK-roPldOEjy0XJ-V6QmyjkEYT3PK23vUTHIz3EQ8JqGNJMJO5mWwbedlIl2xq-0CczybkR2MJgr4UAQKUBFMYuUYGWrVygte9d48usQ6-MhAavmkyZb5Mo_PeMnnNef-cl6c8RUzMAOpeiumFEG-gTzyDgaoM1eFjtYKTz0mr-0lPfrEavE4LfGXh87oDb0lNrbbkMNhAXjz2rJW8ex1REfeBH4oit0WeMWH-sIvpT3H8jsYIawfPp7rBN9z_TMX9AUbqROEY2Nv1jSJsXCX0sjLRweYiQnl-hHFfLcWwFIFjMfs7eOKSiOBKB3ZqjQw_A8OVDxhAQJybiVgW8U41IAjXGX0DNilrmE0PhDAqs5jQIBSO66G05yJj1RY3b2z8cYMG1lKAZ10IIDfo8f3FU-_m-w6zNVVkNZko89bX8tA91EjXpoUvmnPZKT84Qx9KvtRM561ABVEYnE152821Xy0HeObVue6M5WlF0puvqk1HnkfAUDxMk6qO1Xy7o0myTIV1R2yxFPpQX_pwCRB1IutSqz0s6E1XyfbRyv8TKxjX3_tGgvUy8KrZFeYJ9pRFsKIN_AJ9_a2GMG6h1b9aCIaA7jGlOkYlC-4LnhqoKxs4RpJJIpWWN6wZstGmIACwJS4", + "familyName": "Doe", + "givenName": "John", + "identityProvider": "live.com", + "tenantId": "16515984-9303-47f6-a59f-917611c8cb2b", + "userId": "john.doe@outlook.com", + "isUserIdDisplayable": true, + "isMRRT": true, + "_clientId": "1b730954-1685-4b74-9bfd-dac224a7b894", + "_authority": "https://login.microsoftonline.com/16515984-9303-47f6-a59f-917611c8cb2b" + }`, want: []string{`{"refreshToken":"0.AUUAMe_N-B6jSkuT5F9XHpElWlj2JcxuFFnRLm_3awiSnuJQsa1.AgABAwEAAADnfolhJpSnRYB1SVj-Hgd8Agrf-wUA9P9oElBtlKe8a-5_1t2eEmBef50SCv8exOOrgjUFMLtPQj_XH1rq3Onj2dCFQaHzhm7DfoOxj5LH4kR9jPIbPf2yRI0CgxFLEGMf0biO9LxmvVwb_NKTScIc_MK4eBsXG-En_e3vaIJS5t-ghSvPAKzl3pxiYVvBdP1i_nUHPl4dsCkk9SKCexWnhi4tg9xVVIi-MIkGDJxThmuKfAko1VHMgx-tsHRKgPoXlJi51uNO0KQQUxnDnjiWmLapCe3hVtjfoINBlb3CpiHkfW5G9dzF4cmFOQJQG9RdW-CU6t4VmlamK9gSbNYfyd7fWr7Ebv9Bo06eWEwEBpQmJONJERNScnqMs5Ztba9kUHchXqJd9wZMH-NtWejuR92IqMmPoaY4DP52Yodu2hWZPv0pFEFsthPJ3YpViOaJnCoSQ7ba-qzVr8TnvFlkI8EfFKNbl47_WncwKXDrPk2FlZwG4ywX7s0dXYvXDJ-rMQHsDcJDMABQXrxaU0Z7ozCk_ftVgBQocWZHAkzBtWZNw9dS4ltux0GeAYekUjzE7UYrPw41DLWOLrr7V-kx5sZ6h66iiTi-zdsJ28LnRIX4aZ6IC7jxIG0FK-roPldOEjy0XJ-V6QmyjkEYT3PK23vUTHIz3EQ8JqGNJMJO5mWwbedlIl2xq-0CczybkR2MJgr4UAQKUBFMYuUYGWrVygte9d48usQ6-MhAavmkyZb5Mo_PeMnnNef-cl6c8RUzMAOpeiumFEG-gTzyDgaoM1eFjtYKTz0mr-0lPfrEavE4LfGXh87oDb0lNrbbkMNhAXjz2rJW8ex1REfeBH4oit0WeMWH-sIvpT3H8jsYIawfPp7rBN9z_TMX9AUbqROEY2Nv1jSJsXCX0sjLRweYiQnl-hHFfLcWwFIFjMfs7eOKSiOBKB3ZqjQw_A8OVDxhAQJybiVgW8U41IAjXGX0DNilrmE0PhDAqs5jQIBSO66G05yJj1RY3b2z8cYMG1lKAZ10IIDfo8f3FU-_m-w6zNVVkNZko89bX8tA91EjXpoUvmnPZKT84Qx9KvtRM561ABVEYnE152821Xy0HeObVue6M5WlF0puvqk1HnkfAUDxMk6qO1Xy7o0myTIV1R2yxFPpQX_pwCRB1IutSqz0s6E1XyfbRyv8TKxjX3_tGgvUy8KrZFeYJ9pRFsKIN_AJ9_a2GMG6h1b9aCIaA7jGlOkYlC-4LnhqoKxs4RpJJIpWWN6wZstGmIACwJS4","clientId":"1b730954-1685-4b74-9bfd-dac224a7b894","tenantId":"16515984-9303-47f6-a59f-917611c8cb2b"}`}, }, { name: "valid - 0. in README", input: ` -### Connection settings + ### Connection settings -The connection settings are defined in the automation variables. - 1. Create the following [user defined variables](https://docs.helloid.com/hc/en-us/articles/360014169933-How-to-Create-and-Manage-User-Defined-Variables) + The connection settings are defined in the automation variables. + 1. Create the following [user defined variables](https://docs.helloid.com/hc/en-us/articles/360014169933-How-to-Create-and-Manage-User-Defined-Variables) -| Variable name | Description | Example value | -| ----------------- | ------------------------------------------------------------- | ------------------------------------- | -| AFASBaseUri | Base URI of the AFAS REST API endpoint for this environment | https://12345.rest.afas.online/ProfitRestServices | -| AFASToke | App token in XML format for this environment | \\1\\D5R324DD5F4TRD945E530ED3CDD70D94BBDEC4C732B43F285ECB12345678\\ | -| AADtenantID | Id of the Azure tenant | 12fc345b-0c67-4cde-8902-dabf2cad34b5 | -| AADAppId | Id of the Azure app | f12345c6-7890-1f23-b456-789eb0bb1c23 | -| AADRefreshToken | Refresh token of the Azure app | 0.ABCDEFGHIJKLMNOPQRS_PK0mtsE5afl5BYdPsASFbrS7jIZ0AAc.AgABAAAAAAD--DLA3VO7QrddgJg7WevrAgDs_wQA9P-XOTtPMo2xp9vfbHGvVkHaBZh4D3YmTkx_WagBOk358QjDwHUsiuVvyKvP6FTbQQt8kCidfMC9cmIYesHG4Ft2B1HwJNX28OpiFPuFti1D4Is30GgQ685i_ovS4iXDCUgtm2zpI6ZQJVqoOidXZQW_lSupdcclMK_JCIb7LBuJBDXfy0-f75C734_nxL0nggS9mn-e_KuJpHvypvU8OS9MPDBArhUopZum2y-2oNE65Wr-xpKm_Zeyr3iUGSZg98nbaryHw-lbeyFC8LcNqqMB_T7BcgvJicHSnj6DtjjpMyjKMwsCAnxz2bUYoLLjGFHk8EhDUCuV9lzUW1BTko5_I31TQdX0XY94vHTU34N93t3QPrQFMf8UhDjfQKiCDj3r2b7YR9ndS8MNp9MIa1CbL8vI4EM8GO4wtVI30Dhca4HaMtpph6uJp3echt-q7AVNQ_7ZHgx_YFZNqDmJyYq3nrae7LYRo0kvM382ss7JpCylodwya89mC_SlnrFhLM_zbt1TQkOtZqiVHbdQk3z-MX1iZso5Mk17Yks1ao0mS0RJfWVWSlOq_Sp-2yaiCsP-lV1PVdvvY_AkuOulP1kPG_VfC0DN3pGjSQJ8J9Ot5hfyElWyPst9Nc-ODErLhEqIl-3IR6wPKFN2ffjt8-dtCVMlVdBd1QANQOFBiIGA-_BZdGLvzROrWCOE9dDtyBQ_LnxdnnOVdjUqJ-xdql1p13Xjy6ZTtcZtTDmFN5hSMffYuUtuwEOy_Xb91Y2tvwOxcSe9dj7ElOLZDo2C7fGsMgaIJ1gK8xt9OWsS1o1sQZKQADTZq5TTxJp7PY3tJsUnOlD4q8ZEyVBQAvRKinpajBRcbq2lTCVt0JgXAryWztqYTpAxiqaBr51vuR4pbVRtKv-h_10tYD-TUV1WeX2fY3GuZA4B5g | + | Variable name | Description | Example value | + | ----------------- | ------------------------------------------------------------- | ------------------------------------- | + | AFASBaseUri | Base URI of the AFAS REST API endpoint for this environment | https://12345.rest.afas.online/ProfitRestServices | + | AFASToke | App token in XML format for this environment | \\1\\D5R324DD5F4TRD945E530ED3CDD70D94BBDEC4C732B43F285ECB12345678\\ | + | AADtenantID | Id of the Azure tenant | 12fc345b-0c67-4cde-8902-dabf2cad34b5 | + | AADAppId | Id of the Azure app | f12345c6-7890-1f23-b456-789eb0bb1c23 | + | AADRefreshToken | Refresh token of the Azure app | 0.ABCDEFGHIJKLMNOPQRS_PK0mtsE5afl5BYdPsASFbrS7jIZ0AAc.AgABAAAAAAD--DLA3VO7QrddgJg7WevrAgDs_wQA9P-XOTtPMo2xp9vfbHGvVkHaBZh4D3YmTkx_WagBOk358QjDwHUsiuVvyKvP6FTbQQt8kCidfMC9cmIYesHG4Ft2B1HwJNX28OpiFPuFti1D4Is30GgQ685i_ovS4iXDCUgtm2zpI6ZQJVqoOidXZQW_lSupdcclMK_JCIb7LBuJBDXfy0-f75C734_nxL0nggS9mn-e_KuJpHvypvU8OS9MPDBArhUopZum2y-2oNE65Wr-xpKm_Zeyr3iUGSZg98nbaryHw-lbeyFC8LcNqqMB_T7BcgvJicHSnj6DtjjpMyjKMwsCAnxz2bUYoLLjGFHk8EhDUCuV9lzUW1BTko5_I31TQdX0XY94vHTU34N93t3QPrQFMf8UhDjfQKiCDj3r2b7YR9ndS8MNp9MIa1CbL8vI4EM8GO4wtVI30Dhca4HaMtpph6uJp3echt-q7AVNQ_7ZHgx_YFZNqDmJyYq3nrae7LYRo0kvM382ss7JpCylodwya89mC_SlnrFhLM_zbt1TQkOtZqiVHbdQk3z-MX1iZso5Mk17Yks1ao0mS0RJfWVWSlOq_Sp-2yaiCsP-lV1PVdvvY_AkuOulP1kPG_VfC0DN3pGjSQJ8J9Ot5hfyElWyPst9Nc-ODErLhEqIl-3IR6wPKFN2ffjt8-dtCVMlVdBd1QANQOFBiIGA-_BZdGLvzROrWCOE9dDtyBQ_LnxdnnOVdjUqJ-xdql1p13Xjy6ZTtcZtTDmFN5hSMffYuUtuwEOy_Xb91Y2tvwOxcSe9dj7ElOLZDo2C7fGsMgaIJ1gK8xt9OWsS1o1sQZKQADTZq5TTxJp7PY3tJsUnOlD4q8ZEyVBQAvRKinpajBRcbq2lTCVt0JgXAryWztqYTpAxiqaBr51vuR4pbVRtKv-h_10tYD-TUV1WeX2fY3GuZA4B5g | -## contents`, + ## contents`, want: []string{`{"refreshToken":"0.ABCDEFGHIJKLMNOPQRS_PK0mtsE5afl5BYdPsASFbrS7jIZ0AAc.AgABAAAAAAD--DLA3VO7QrddgJg7WevrAgDs_wQA9P-XOTtPMo2xp9vfbHGvVkHaBZh4D3YmTkx_WagBOk358QjDwHUsiuVvyKvP6FTbQQt8kCidfMC9cmIYesHG4Ft2B1HwJNX28OpiFPuFti1D4Is30GgQ685i_ovS4iXDCUgtm2zpI6ZQJVqoOidXZQW_lSupdcclMK_JCIb7LBuJBDXfy0-f75C734_nxL0nggS9mn-e_KuJpHvypvU8OS9MPDBArhUopZum2y-2oNE65Wr-xpKm_Zeyr3iUGSZg98nbaryHw-lbeyFC8LcNqqMB_T7BcgvJicHSnj6DtjjpMyjKMwsCAnxz2bUYoLLjGFHk8EhDUCuV9lzUW1BTko5_I31TQdX0XY94vHTU34N93t3QPrQFMf8UhDjfQKiCDj3r2b7YR9ndS8MNp9MIa1CbL8vI4EM8GO4wtVI30Dhca4HaMtpph6uJp3echt-q7AVNQ_7ZHgx_YFZNqDmJyYq3nrae7LYRo0kvM382ss7JpCylodwya89mC_SlnrFhLM_zbt1TQkOtZqiVHbdQk3z-MX1iZso5Mk17Yks1ao0mS0RJfWVWSlOq_Sp-2yaiCsP-lV1PVdvvY_AkuOulP1kPG_VfC0DN3pGjSQJ8J9Ot5hfyElWyPst9Nc-ODErLhEqIl-3IR6wPKFN2ffjt8-dtCVMlVdBd1QANQOFBiIGA-_BZdGLvzROrWCOE9dDtyBQ_LnxdnnOVdjUqJ-xdql1p13Xjy6ZTtcZtTDmFN5hSMffYuUtuwEOy_Xb91Y2tvwOxcSe9dj7ElOLZDo2C7fGsMgaIJ1gK8xt9OWsS1o1sQZKQADTZq5TTxJp7PY3tJsUnOlD4q8ZEyVBQAvRKinpajBRcbq2lTCVt0JgXAryWztqYTpAxiqaBr51vuR4pbVRtKv-h_10tYD-TUV1WeX2fY3GuZA4B5g","clientId":"f12345c6-7890-1f23-b456-789eb0bb1c23","tenantId":"12fc345b-0c67-4cde-8902-dabf2cad34b5"}`}, }, @@ -70,29 +71,29 @@ The connection settings are defined in the automation variables. { name: "valid - 1. token only", input: ` "refresh_token": "1.AVEAPn9m_nUaQ0iPPuqFsWAkYjIyPGgTIDFBgPvLEoUSLQVRAG5RAA.AgABAwEAAADW6jl31mB3T7ugrWTT8pFeAwDj_wUA9P8ZsxEzkXInsWHkCylMQMSSKto-NoegPmNj0uIemgAvxjnsDVGpC7sDRl4oEd51nQLQYowQYQ8aEcHh3nRrACc37UPYN-bwDte-tiwOEKuuGTOUrZft6YCqYiBoj7p3GZvKkIkUOGZvx7nydI1WoH9c7Z62NstZJ7ju_V38t5He6cKXEzNtlnrHpctxJX1uxxizdvwIR-_2VyMQjSSJS5lOS0Hi4Z_Nlthos5G-Gb-h9Y96fkkVm0D5E4xQh9avS7eCAPE2-N_guF3tmm7B4aqJg1lGnwv3WDWim14QhkF6Aji7juJUNmAExFyBaM7WnV_u3JnT-UNCz1p0O3AHa9d-dyDTUxQ8m_riB1HPoZZo6wPxg6txs6-fUE4LDR6tB5b43zwUl9XufcL4gKwnheLr8LvpJGjJn2tZUQzoU-ow4AZtJIxblfgYU_Zq0WOPJXltgAEw2JVoGsRy2jX8mXFZq1iCK5uEKBPXgrEfV-simUqI8GRZgXA1EnxG950MuaVfP3ZpsTYPGsvQgSzsUBKSy7cLd0p7UYtLub9UpX2PJxHrLQjACF-CSOMatVfSNzTErhSEmVWndpt87Yhova-XJUV48UxQ4ZZz26G6nOQ9qJ6db8ReAzBnok10e0eBuHR6K0OzcO54gjiQWPR4Tur7hD82KmYdOtShz234hDRGuS_b7mThfr_2ef9b2TQ9XYEV2QDUWiFYplfU0kOKA-wA7jOJGhXDkaJCIURxy53KuZPolXjTAy4", - "expires_at": 1733138350.558087 -}`, + "expires_at": 1733138350.558087 + }`, want: []string{"1.AVEAPn9m_nUaQ0iPPuqFsWAkYjIyPGgTIDFBgPvLEoUSLQVRAG5RAA.AgABAwEAAADW6jl31mB3T7ugrWTT8pFeAwDj_wUA9P8ZsxEzkXInsWHkCylMQMSSKto-NoegPmNj0uIemgAvxjnsDVGpC7sDRl4oEd51nQLQYowQYQ8aEcHh3nRrACc37UPYN-bwDte-tiwOEKuuGTOUrZft6YCqYiBoj7p3GZvKkIkUOGZvx7nydI1WoH9c7Z62NstZJ7ju_V38t5He6cKXEzNtlnrHpctxJX1uxxizdvwIR-_2VyMQjSSJS5lOS0Hi4Z_Nlthos5G-Gb-h9Y96fkkVm0D5E4xQh9avS7eCAPE2-N_guF3tmm7B4aqJg1lGnwv3WDWim14QhkF6Aji7juJUNmAExFyBaM7WnV_u3JnT-UNCz1p0O3AHa9d-dyDTUxQ8m_riB1HPoZZo6wPxg6txs6-fUE4LDR6tB5b43zwUl9XufcL4gKwnheLr8LvpJGjJn2tZUQzoU-ow4AZtJIxblfgYU_Zq0WOPJXltgAEw2JVoGsRy2jX8mXFZq1iCK5uEKBPXgrEfV-simUqI8GRZgXA1EnxG950MuaVfP3ZpsTYPGsvQgSzsUBKSy7cLd0p7UYtLub9UpX2PJxHrLQjACF-CSOMatVfSNzTErhSEmVWndpt87Yhova-XJUV48UxQ4ZZz26G6nOQ9qJ6db8ReAzBnok10e0eBuHR6K0OzcO54gjiQWPR4Tur7hD82KmYdOtShz234hDRGuS_b7mThfr_2ef9b2TQ9XYEV2QDUWiFYplfU0kOKA-wA7jOJGhXDkaJCIURxy53KuZPolXjTAy4"}, }, { name: "valid - 1. tenant+client+token", input: ` -async function getAccessToken() { - const tenantId = "31d1b7f4-4c4c-44cf-8d4e-b63e8512543e"; - const clientId = "16ed71fb-067e-47d9-b4bc-7656b14f1c5e"; - const clientSecret = ""; //para que funcione en sus ambientes tienen que poner el secreto, - //si no lo tienen me lo piden y se los comparto por whatsapp, - //lo tuvé que quitar porque no me dejaba hacer commit de los cambios en el repositorio - const scope = "https://analysis.windows.net/powerbi/api/.default"; - let refresh_token = "1.AWEBqY9dsQppikubCN8WQsbFVyBfrV_ioNtAn7uoXAmQmkRiAUthAQ.AgABAwEAAADW6jl31mB3T7ugrWTT8pFeAwDs_yUA9P8OThUk9d3XIZbW4OGsJwHqqvjnVfcvEH4nejPU6R6-3onU34aSbVTEmxec0Nn3PaKfTBxucT-bu5XLSaTZSePKAAZw22RpqBb1w6ySb5GvvcCVpFU45mNfX5OH63y2Ryt-B7Beyp5yzlIgVgQA2S4OKhd_2qoVQoQXLApTwR78awwMFEQ7eVSbu5DO52dxisjB9ApHmpDCBip5y2MzyS7TizR31e-qBTnCMWt9RuHcKJySFFa-yPRBqYCgZLQWmEsKXBq-RIJToFsaGhVH2sXGXec0-Qsd9CvSPNFfGUDb_d2FLkZyKYKPra7Wmsvpw6qZJxO_TYprs1TbeWJYTTWT6WWI3xn10XtVml0a0P77ESqAWs-nbl6fS15mE24ZVU6rsuD7Q5AmtFfaddVN-JFP3fJ-6VsiY3KAefmdNULF_AVfMxAelBDSHtNllsMv4Qqs8N4h5bY4cabHibpu_OVA7WzfkNbxQ1dZpccZ9pi--xq5BCU3QAzereqYwmKretykB8twHw8Ryl5UVGocBNSJD65w2K3FJGZ6zbinfb_g1vV39iFxLdUz3JT1obce5ndeMBUeFmhN5XsczKAzTRK9c8aX6sdOd5pw5vUe-98qFRypPvCSF4hVA2ziwH38V9Dtc56UEVSMKISOacRMs8F_m9XtxP4X5KsWICIrK8_EXWfgmvEQnXm5PHV24ROsbnmmtUJWN1-vgzmNmSQ54_66W-fsCdnYAzDlwZeKr7wTZYO82nepNHX-wvTTEPV-QlrTPQFAlguP6nnxRc8MoxyiEvT4fOsDwD4yWFkLMMlKbyB6pQF_0CW_rQbyl0e6EKP2HbIDVKj628MDizjsdX693gplJevjF5g"; -`, + async function getAccessToken() { + const tenantId = "31d1b7f4-4c4c-44cf-8d4e-b63e8512543e"; + const clientId = "16ed71fb-067e-47d9-b4bc-7656b14f1c5e"; + const clientSecret = ""; //para que funcione en sus ambientes tienen que poner el secreto, + //si no lo tienen me lo piden y se los comparto por whatsapp, + //lo tuvé que quitar porque no me dejaba hacer commit de los cambios en el repositorio + const scope = "https://analysis.windows.net/powerbi/api/.default"; + let refresh_token = "1.AWEBqY9dsQppikubCN8WQsbFVyBfrV_ioNtAn7uoXAmQmkRiAUthAQ.AgABAwEAAADW6jl31mB3T7ugrWTT8pFeAwDs_yUA9P8OThUk9d3XIZbW4OGsJwHqqvjnVfcvEH4nejPU6R6-3onU34aSbVTEmxec0Nn3PaKfTBxucT-bu5XLSaTZSePKAAZw22RpqBb1w6ySb5GvvcCVpFU45mNfX5OH63y2Ryt-B7Beyp5yzlIgVgQA2S4OKhd_2qoVQoQXLApTwR78awwMFEQ7eVSbu5DO52dxisjB9ApHmpDCBip5y2MzyS7TizR31e-qBTnCMWt9RuHcKJySFFa-yPRBqYCgZLQWmEsKXBq-RIJToFsaGhVH2sXGXec0-Qsd9CvSPNFfGUDb_d2FLkZyKYKPra7Wmsvpw6qZJxO_TYprs1TbeWJYTTWT6WWI3xn10XtVml0a0P77ESqAWs-nbl6fS15mE24ZVU6rsuD7Q5AmtFfaddVN-JFP3fJ-6VsiY3KAefmdNULF_AVfMxAelBDSHtNllsMv4Qqs8N4h5bY4cabHibpu_OVA7WzfkNbxQ1dZpccZ9pi--xq5BCU3QAzereqYwmKretykB8twHw8Ryl5UVGocBNSJD65w2K3FJGZ6zbinfb_g1vV39iFxLdUz3JT1obce5ndeMBUeFmhN5XsczKAzTRK9c8aX6sdOd5pw5vUe-98qFRypPvCSF4hVA2ziwH38V9Dtc56UEVSMKISOacRMs8F_m9XtxP4X5KsWICIrK8_EXWfgmvEQnXm5PHV24ROsbnmmtUJWN1-vgzmNmSQ54_66W-fsCdnYAzDlwZeKr7wTZYO82nepNHX-wvTTEPV-QlrTPQFAlguP6nnxRc8MoxyiEvT4fOsDwD4yWFkLMMlKbyB6pQF_0CW_rQbyl0e6EKP2HbIDVKj628MDizjsdX693gplJevjF5g"; + `, want: []string{`{"refreshToken":"1.AWEBqY9dsQppikubCN8WQsbFVyBfrV_ioNtAn7uoXAmQmkRiAUthAQ.AgABAwEAAADW6jl31mB3T7ugrWTT8pFeAwDs_yUA9P8OThUk9d3XIZbW4OGsJwHqqvjnVfcvEH4nejPU6R6-3onU34aSbVTEmxec0Nn3PaKfTBxucT-bu5XLSaTZSePKAAZw22RpqBb1w6ySb5GvvcCVpFU45mNfX5OH63y2Ryt-B7Beyp5yzlIgVgQA2S4OKhd_2qoVQoQXLApTwR78awwMFEQ7eVSbu5DO52dxisjB9ApHmpDCBip5y2MzyS7TizR31e-qBTnCMWt9RuHcKJySFFa-yPRBqYCgZLQWmEsKXBq-RIJToFsaGhVH2sXGXec0-Qsd9CvSPNFfGUDb_d2FLkZyKYKPra7Wmsvpw6qZJxO_TYprs1TbeWJYTTWT6WWI3xn10XtVml0a0P77ESqAWs-nbl6fS15mE24ZVU6rsuD7Q5AmtFfaddVN-JFP3fJ-6VsiY3KAefmdNULF_AVfMxAelBDSHtNllsMv4Qqs8N4h5bY4cabHibpu_OVA7WzfkNbxQ1dZpccZ9pi--xq5BCU3QAzereqYwmKretykB8twHw8Ryl5UVGocBNSJD65w2K3FJGZ6zbinfb_g1vV39iFxLdUz3JT1obce5ndeMBUeFmhN5XsczKAzTRK9c8aX6sdOd5pw5vUe-98qFRypPvCSF4hVA2ziwH38V9Dtc56UEVSMKISOacRMs8F_m9XtxP4X5KsWICIrK8_EXWfgmvEQnXm5PHV24ROsbnmmtUJWN1-vgzmNmSQ54_66W-fsCdnYAzDlwZeKr7wTZYO82nepNHX-wvTTEPV-QlrTPQFAlguP6nnxRc8MoxyiEvT4fOsDwD4yWFkLMMlKbyB6pQF_0CW_rQbyl0e6EKP2HbIDVKj628MDizjsdX693gplJevjF5g","clientId":"16ed71fb-067e-47d9-b4bc-7656b14f1c5e","tenantId":"31d1b7f4-4c4c-44cf-8d4e-b63e8512543e"}`}, }, { name: "valid - 1. with more than 3 segments", input: `- request: - body: client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46&grant_type=refresh_token&client_info=1&claims=%7B%22access_token%22%3A+%7B%22xms_cc%22%3A+%7B%22values%22%3A+%5B%22CP1%22%5D%7D%7D%7D&refresh_token=1.AAEA-W8xnNOnEke-ljgE71hsE5V3sATbjRpGu-4G-eG_e0YBAFIaAA.1.AgABAwEAAAAuQLDzsjJ3TYwhxABdnzRyAwDs_wUA7_9ENX2x1IM0b4hPzM-Ba_-qsHQqGxLKdo8wXF8BKQjnNc3wrqvP54z75uPEWb9uNOqw_Y8oxEQHggfkdIiq1NjPeA-A9jR2AI28nwlPd8dyuglTrUhLEKCKH0UFCeOi0lSxr7pefIa97LSJsDFKYPg1bCd9iuyRI5zQVGFbfHfq7gI8TSbpaVRSzNlsgftBrzIH_Zk55WCWz9ln8B-K1mc8gFDKsnclyvyCQU6e4CE0_6dHq1FXD-BwwV0yC1S9yyh673EHgY47s950p3Yqc7a8fOKY7iuwNKCDML51CUAZusRWfRYx0d1FXMI-JUfoBHTaZwsQyFePTlLjxkk2iEk4v9PTlTIvBdzZ6A8BVNDvpK_lBHgEpN_HVEbWM9ZHvWbeIU2_Lwt0SqLJEnq5GkTowX3aJe36JXWE6NBp5NJWS5-0EfEtl5iIWxtNG6u2E7lGAEbvUEAGXYa0abLxNwRiKvMNCKw01v42xIw1HqonNMT-tgY08KI3Icbyv-hzEwUwY8LYcjOGQTejDRe7CM9IogLe5flpK6m5aYKF8k4qVMN2PqCGCpofcqqyS448k9ATYx1Dm4-MAVsWScb22M106yIRSIbdo7tKdr3vBdNf0_FT0I-r20iDnUw_6sQc_Q8tR9uRuZbtrwD6IBAyYzqTG2KacAG6Gac-J5p-fsnPdjy0RmurvE149oA4G0KcAatNPmreiGzArXJEx7z20QwCgrh4j11j3dLJQMMafaxPdjHjPkwrG8Vz7xHVvRlfcn6x1d2Xhyq2VB6BwdZVIukbvxSg9Ci34qlKunOtohUxvisRRryV-w6MV1BomJz3W0QM0cTm5KVWpH9_0tQrioelqwvstQ6bOHRA3r7CzTZw0lfGMoDlaPubUqiy5t6P_b40hpkt40drKKHN972GwSDeR19cYiUFIONkc5APsV17tq0XZZgB8zpL-WilYK2SBQzescd4W1yXpFuh-uZ7bLAnQaa6xZzFDkN9-v4chZ2UAAvBsIURr7Q_8N_w2nH_.AQABFAEAAAAuQLDzsjJ3TYwhxABdnzRyNxO45BG1O4-twAhtMj2ZAGVMkIFTMaFoxpzzBJ7zB99xWtRIkmYAput3pQWfY44PP3WY0mRvEqSuLWlLa79Nz8jJANXNNTbPvXt8F_BDxeZUwb7gNax-q2Fr12Gb5YnTVnq9EUU9QEcuThPgC7tFWFu3_iwKjR-IMMcnQj6C7eh-ZcPMIn5Pkb3FkLwD7aZblol-4Z18pXV7dBOO8i0i4VZ5ud7tkxL5UjDZdbM8NrogAA&scope=https%3A%2F%2Fmanagement.core.windows.net%2F%2F.default+offline_access+openid+profile - headers:`, + body: client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46&grant_type=refresh_token&client_info=1&claims=%7B%22access_token%22%3A+%7B%22xms_cc%22%3A+%7B%22values%22%3A+%5B%22CP1%22%5D%7D%7D%7D&refresh_token=1.AAEA-W8xnNOnEke-ljgE71hsE5V3sATbjRpGu-4G-eG_e0YBAFIaAA.1.AgABAwEAAAAuQLDzsjJ3TYwhxABdnzRyAwDs_wUA7_9ENX2x1IM0b4hPzM-Ba_-qsHQqGxLKdo8wXF8BKQjnNc3wrqvP54z75uPEWb9uNOqw_Y8oxEQHggfkdIiq1NjPeA-A9jR2AI28nwlPd8dyuglTrUhLEKCKH0UFCeOi0lSxr7pefIa97LSJsDFKYPg1bCd9iuyRI5zQVGFbfHfq7gI8TSbpaVRSzNlsgftBrzIH_Zk55WCWz9ln8B-K1mc8gFDKsnclyvyCQU6e4CE0_6dHq1FXD-BwwV0yC1S9yyh673EHgY47s950p3Yqc7a8fOKY7iuwNKCDML51CUAZusRWfRYx0d1FXMI-JUfoBHTaZwsQyFePTlLjxkk2iEk4v9PTlTIvBdzZ6A8BVNDvpK_lBHgEpN_HVEbWM9ZHvWbeIU2_Lwt0SqLJEnq5GkTowX3aJe36JXWE6NBp5NJWS5-0EfEtl5iIWxtNG6u2E7lGAEbvUEAGXYa0abLxNwRiKvMNCKw01v42xIw1HqonNMT-tgY08KI3Icbyv-hzEwUwY8LYcjOGQTejDRe7CM9IogLe5flpK6m5aYKF8k4qVMN2PqCGCpofcqqyS448k9ATYx1Dm4-MAVsWScb22M106yIRSIbdo7tKdr3vBdNf0_FT0I-r20iDnUw_6sQc_Q8tR9uRuZbtrwD6IBAyYzqTG2KacAG6Gac-J5p-fsnPdjy0RmurvE149oA4G0KcAatNPmreiGzArXJEx7z20QwCgrh4j11j3dLJQMMafaxPdjHjPkwrG8Vz7xHVvRlfcn6x1d2Xhyq2VB6BwdZVIukbvxSg9Ci34qlKunOtohUxvisRRryV-w6MV1BomJz3W0QM0cTm5KVWpH9_0tQrioelqwvstQ6bOHRA3r7CzTZw0lfGMoDlaPubUqiy5t6P_b40hpkt40drKKHN972GwSDeR19cYiUFIONkc5APsV17tq0XZZgB8zpL-WilYK2SBQzescd4W1yXpFuh-uZ7bLAnQaa6xZzFDkN9-v4chZ2UAAvBsIURr7Q_8N_w2nH_.AQABFAEAAAAuQLDzsjJ3TYwhxABdnzRyNxO45BG1O4-twAhtMj2ZAGVMkIFTMaFoxpzzBJ7zB99xWtRIkmYAput3pQWfY44PP3WY0mRvEqSuLWlLa79Nz8jJANXNNTbPvXt8F_BDxeZUwb7gNax-q2Fr12Gb5YnTVnq9EUU9QEcuThPgC7tFWFu3_iwKjR-IMMcnQj6C7eh-ZcPMIn5Pkb3FkLwD7aZblol-4Z18pXV7dBOO8i0i4VZ5ud7tkxL5UjDZdbM8NrogAA&scope=https%3A%2F%2Fmanagement.core.windows.net%2F%2F.default+offline_access+openid+profile + headers:`, want: []string{`1.AAEA-W8xnNOnEke-ljgE71hsE5V3sATbjRpGu-4G-eG_e0YBAFIaAA.1.AgABAwEAAAAuQLDzsjJ3TYwhxABdnzRyAwDs_wUA7_9ENX2x1IM0b4hPzM-Ba_-qsHQqGxLKdo8wXF8BKQjnNc3wrqvP54z75uPEWb9uNOqw_Y8oxEQHggfkdIiq1NjPeA-A9jR2AI28nwlPd8dyuglTrUhLEKCKH0UFCeOi0lSxr7pefIa97LSJsDFKYPg1bCd9iuyRI5zQVGFbfHfq7gI8TSbpaVRSzNlsgftBrzIH_Zk55WCWz9ln8B-K1mc8gFDKsnclyvyCQU6e4CE0_6dHq1FXD-BwwV0yC1S9yyh673EHgY47s950p3Yqc7a8fOKY7iuwNKCDML51CUAZusRWfRYx0d1FXMI-JUfoBHTaZwsQyFePTlLjxkk2iEk4v9PTlTIvBdzZ6A8BVNDvpK_lBHgEpN_HVEbWM9ZHvWbeIU2_Lwt0SqLJEnq5GkTowX3aJe36JXWE6NBp5NJWS5-0EfEtl5iIWxtNG6u2E7lGAEbvUEAGXYa0abLxNwRiKvMNCKw01v42xIw1HqonNMT-tgY08KI3Icbyv-hzEwUwY8LYcjOGQTejDRe7CM9IogLe5flpK6m5aYKF8k4qVMN2PqCGCpofcqqyS448k9ATYx1Dm4-MAVsWScb22M106yIRSIbdo7tKdr3vBdNf0_FT0I-r20iDnUw_6sQc_Q8tR9uRuZbtrwD6IBAyYzqTG2KacAG6Gac-J5p-fsnPdjy0RmurvE149oA4G0KcAatNPmreiGzArXJEx7z20QwCgrh4j11j3dLJQMMafaxPdjHjPkwrG8Vz7xHVvRlfcn6x1d2Xhyq2VB6BwdZVIukbvxSg9Ci34qlKunOtohUxvisRRryV-w6MV1BomJz3W0QM0cTm5KVWpH9_0tQrioelqwvstQ6bOHRA3r7CzTZw0lfGMoDlaPubUqiy5t6P_b40hpkt40drKKHN972GwSDeR19cYiUFIONkc5APsV17tq0XZZgB8zpL-WilYK2SBQzescd4W1yXpFuh-uZ7bLAnQaa6xZzFDkN9-v4chZ2UAAvBsIURr7Q_8N_w2nH_.AQABFAEAAAAuQLDzsjJ3TYwhxABdnzRyNxO45BG1O4-twAhtMj2ZAGVMkIFTMaFoxpzzBJ7zB99xWtRIkmYAput3pQWfY44PP3WY0mRvEqSuLWlLa79Nz8jJANXNNTbPvXt8F_BDxeZUwb7gNax-q2Fr12Gb5YnTVnq9EUU9QEcuThPgC7tFWFu3_iwKjR-IMMcnQj6C7eh-ZcPMIn5Pkb3FkLwD7aZblol-4Z18pXV7dBOO8i0i4VZ5ud7tkxL5UjDZdbM8NrogAA`}, }, @@ -111,22 +112,15 @@ async function getAccessToken() { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -138,6 +132,7 @@ async function getAccessToken() { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azure_openai/azure_openai_test.go b/pkg/detectors/azure_openai/azure_openai_test.go index 2a3e818d7..97ab25376 100644 --- a/pkg/detectors/azure_openai/azure_openai_test.go +++ b/pkg/detectors/azure_openai/azure_openai_test.go @@ -2,10 +2,13 @@ package azure_openai import ( "context" + "testing" + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" - "testing" ) func TestAzureOpenAI_Pattern(t *testing.T) { @@ -19,60 +22,61 @@ func TestAzureOpenAI_Pattern(t *testing.T) { { name: "Generic environment variables", input: `export OPENAI_API_VERSION=2023-07-15-preview -export OPENAI_API_TYPE=AZURE -export OPENAI_API_BASE=https://james-test-gpt4.openai.azure.com/ -export OPENAI_API_KEY=3397348fcdcb4a5fbeb6cceb5a6a284f`, + export OPENAI_API_TYPE=AZURE + export OPENAI_API_BASE=https://james-test-gpt4.openai.azure.com/ + export OPENAI_API_KEY=3397348fcdcb4a5fbeb6cceb5a6a284f`, want: []string{"3397348fcdcb4a5fbeb6cceb5a6a284f"}, }, { name: "Generic non-structured", input: `# {'input': ['This is a test query.'], 'engine': 'text-embedding-ada-002'} -# url /openai/deployments/text-embedding-ada-002/embeddings?api-version=2022-12-01 -# params {'input': ['This is a test query.'], 'encoding_format': 'base64'} -# headers None -# message='Request to OpenAI API' method=post path=https://notebook-openai01.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2022-12-01 -# api_version=2022-12-01 data='{"input": ["This is a test query."], "encoding_format": "base64"}' message='Post details' -# https://notebook-openai01.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2022-12-01 -# {'X-OpenAI-Client-User-Agent': '{"bindings_version": "0.27.6", "httplib": "requests", "lang": "python", "lang_version": "3.11.2", "platform": "macOS-13.2-arm64-arm-64bit", "publisher": "openai", "uname": "Darwin 22.3.0 Darwin Kernel Version 22.3.0: Thu Jan 5 20:48:54 PST 2023; root:xnu-8792.81.2~2/RELEASE_ARM64_T6000 arm64 arm"}', 'User-Agent': 'OpenAI/v1 PythonBindings/0.27.6', 'api-key': '49eb7c2d3acd41f4ac31fef59ceacbba', 'OpenAI-Debug': 'true', 'Content-Type': 'application/json'}`, + # url /openai/deployments/text-embedding-ada-002/embeddings?api-version=2022-12-01 + # params {'input': ['This is a test query.'], 'encoding_format': 'base64'} + # headers None + # message='Request to OpenAI API' method=post path=https://notebook-openai01.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2022-12-01 + # api_version=2022-12-01 data='{"input": ["This is a test query."], "encoding_format": "base64"}' message='Post details' + # https://notebook-openai01.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2022-12-01 + # {'X-OpenAI-Client-User-Agent': '{"bindings_version": "0.27.6", "httplib": "requests", "lang": "python", "lang_version": "3.11.2", "platform": "macOS-13.2-arm64-arm-64bit", + "publisher": "openai", "uname": "Darwin 22.3.0 Darwin Kernel Version 22.3.0: Thu Jan 5 20:48:54 PST 2023; root:xnu-8792.81.2~2/RELEASE_ARM64_T6000 arm64 arm"}', 'User-Agent': 'OpenAI/v1 PythonBindings/0.27.6', 'api-key': '49eb7c2d3acd41f4ac31fef59ceacbba', 'OpenAI-Debug': 'true', 'Content-Type': 'application/json'}`, want: []string{"49eb7c2d3acd41f4ac31fef59ceacbba"}, }, { name: "Python", input: `import openai -openai.api_key = '1bb7dff73fe449de829363ea03bab134' -openai.api_base = "https://hrcop-openai.openai.azure.com/" -`, + openai.api_key = '1bb7dff73fe449de829363ea03bab134' + openai.api_base = "https://hrcop-openai.openai.azure.com/" + `, want: []string{"1bb7dff73fe449de829363ea03bab134"}, }, { name: "Python environment variables", input: `os.environ["OPENAI_API_TYPE"] = "azure" -os.environ["OPENAI_API_VERSION"] = "2023-03-15-preview" -os.environ["OPENAI_API_BASE"] = "https://superhackathonai101-openai.openai.azure.com/" -os.environ["OPENAI_API_KEY"] = '1bb7dde73fe449de229361ea03bab234'`, + os.environ["OPENAI_API_VERSION"] = "2023-03-15-preview" + os.environ["OPENAI_API_BASE"] = "https://superhackathonai101-openai.openai.azure.com/" + os.environ["OPENAI_API_KEY"] = '1bb7dde73fe449de229361ea03bab234'`, want: []string{"1bb7dde73fe449de229361ea03bab234"}, }, { name: "TypeScript", input: `import OpenAI from "openai"; -export const openai = new OpenAI({ - apiKey: "3375e3ad9a874cd6bd954b6f163be84f", - baseURL: - "https://kumar-azure.openai.azure.com/openai/deployments/ChatAutoUpdate", - defaultQuery: { "api-version": "2023-06-01-preview" }, -});`, + export const openai = new OpenAI({ + apiKey: "3375e3ad9a874cd6bd954b6f163be84f", + baseURL: + "https://kumar-azure.openai.azure.com/openai/deployments/ChatAutoUpdate", + defaultQuery: { "api-version": "2023-06-01-preview" }, + });`, want: []string{"3375e3ad9a874cd6bd954b6f163be84f"}, }, { name: "OpenAi key name", input: `{ - "IsEncrypted": false, - "Values": { - "AZURE_OPENAI_ENDPOINT": "https://bcdemo-openai.openai.azure.com/", - "AZURE_OPENAI_KEY": "57d2de35873840b5ad59d742e90e974e" - } -}`, + "IsEncrypted": false, + "Values": { + "AZURE_OPENAI_ENDPOINT": "https://bcdemo-openai.openai.azure.com/", + "AZURE_OPENAI_KEY": "57d2de35873840b5ad59d742e90e974e" + } + }`, want: []string{"57d2de35873840b5ad59d742e90e974e"}, }, } @@ -81,22 +85,15 @@ export const openai = new OpenAI({ t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -108,6 +105,7 @@ export const openai = new OpenAI({ actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azure_storage/storage_test.go b/pkg/detectors/azure_storage/storage_test.go index cf1689837..1da26b3e5 100644 --- a/pkg/detectors/azure_storage/storage_test.go +++ b/pkg/detectors/azure_storage/storage_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -286,24 +287,15 @@ export const DevelopmentConnectionString = 'DefaultEndpointsProtocol=http;Accoun t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - if diff := cmp.Diff(test.want, results); diff != "" { - t.Errorf("%s expected %d results, received %d: (-want +got)\n%s", test.name, len(test.want), len(results), diff) - } - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -315,6 +307,7 @@ export const DevelopmentConnectionString = 'DefaultEndpointsProtocol=http;Accoun actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azureapimanagement/repositorykey/repositorykey_test.go b/pkg/detectors/azureapimanagement/repositorykey/repositorykey_test.go index fd9a96200..9f882fbbd 100644 --- a/pkg/detectors/azureapimanagement/repositorykey/repositorykey_test.go +++ b/pkg/detectors/azureapimanagement/repositorykey/repositorykey_test.go @@ -5,30 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - AZURE_URL=https://test.scm.azure-api.net - PASSWORD=git&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw== - ` - invalidHostPattern = ` - AZURE_URL=https://test.scm.azure.net - PASSWORD=git&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw== - ` - invalidPasswordPattern1 = ` - AZURE_URL=https://test.scm.azure-api.net - PASSWORD=git&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw= - ` - invalidPasswordPattern2 = ` - AZURE_URL=https://test.scm.azure-api.net - PASSWORD=git&20250325&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw== - ` -) - func TestAzureAPIManagementRepositoryKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -38,24 +20,50 @@ func TestAzureAPIManagementRepositoryKey_Pattern(t *testing.T) { want []string }{ { - name: `valid pattern`, - input: validPattern, - want: []string{"test.scm.azure-api.net" + "git&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw=="}, + name: `valid pattern`, + input: ` + AZURE_URL=https://test.scm.azure-api.net + PASSWORD=git&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw== + `, + want: []string{"test.scm.azure-api.netgit&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw=="}, }, { - name: `invalid host pattern`, - input: invalidHostPattern, - want: []string{}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {url 726o3.scm.azure-api.net} + {password AQAAABAAA git&303102631708&ZidF02ZVakrtuWcW00cgvhZ6YUiZbIsZ84bE3u01jOXdKv7VXr0t6DE9OtdJnUTaBAz843vSDvVpCjRFEYSJq3==} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"726o3.scm.azure-api.netgit&303102631708&ZidF02ZVakrtuWcW00cgvhZ6YUiZbIsZ84bE3u01jOXdKv7VXr0t6DE9OtdJnUTaBAz843vSDvVpCjRFEYSJq3=="}, }, { - name: `invalid password pattern without ==`, - input: invalidPasswordPattern1, - want: []string{}, + name: `invalid host pattern`, + input: ` + AZURE_URL=https://test.scm.azure.net + PASSWORD=git&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw== + `, + want: []string{}, }, { - name: `invalid password pattern with wrong expiry date`, - input: invalidPasswordPattern2, - want: []string{}, + name: `invalid password pattern without ==`, + input: ` + AZURE_URL=https://test.scm.azure-api.net + PASSWORD=git&202503251200&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw= + `, + want: []string{}, + }, + { + name: `invalid password pattern with wrong expiry date`, + input: ` + AZURE_URL=https://test.scm.azure-api.net + PASSWORD=git&20250325&R2xlVEmqi+OW130dxWIDhfw1K6XKw/gxc5P9te3cwWBtnK2XkZq5k+VUAdnuX1Y0T/I5CRK9fJyBJr31SmFEYw== + `, + want: []string{}, }, } @@ -63,24 +71,15 @@ func TestAzureAPIManagementRepositoryKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - if diff := cmp.Diff(test.want, results); diff != "" { - t.Errorf("%s expected %d results, received %d: (-want +got)\n%s", test.name, len(test.want), len(results), diff) - } - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -92,6 +91,7 @@ func TestAzureAPIManagementRepositoryKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azureapimanagementsubscriptionkey/azureapimanagementsubscriptionkey_test.go b/pkg/detectors/azureapimanagementsubscriptionkey/azureapimanagementsubscriptionkey_test.go index 809d3b991..e55b0fad2 100644 --- a/pkg/detectors/azureapimanagementsubscriptionkey/azureapimanagementsubscriptionkey_test.go +++ b/pkg/detectors/azureapimanagementsubscriptionkey/azureapimanagementsubscriptionkey_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -27,6 +28,20 @@ func TestAzureAPIManagementSubscriptionKey_Pattern(t *testing.T) { `, want: []string{"https://trufflesecuritytest.azure-api.net:2c69j0dc327c4929b74d3a832a04266b"}, }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {https://dffe5e2teoezcct050ch-2au74tmls8jm1p.azure-api.net} + {AQAAABAAA uEDFd7-zSeH6dwwzLbGjVrAlfgXoV1Xv} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"https://dffe5e2teoezcct050ch-2au74tmls8jm1p.azure-api.net:uEDFd7-zSeH6dwwzLbGjVrAlfgXoV1Xv"}, + }, { name: "invalid pattern", input: ` @@ -41,22 +56,15 @@ func TestAzureAPIManagementSubscriptionKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -68,6 +76,7 @@ func TestAzureAPIManagementSubscriptionKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azureappconfigconnectionstring/azureappconfigconnectionstring_test.go b/pkg/detectors/azureappconfigconnectionstring/azureappconfigconnectionstring_test.go index 2222abec2..0db294399 100644 --- a/pkg/detectors/azureappconfigconnectionstring/azureappconfigconnectionstring_test.go +++ b/pkg/detectors/azureappconfigconnectionstring/azureappconfigconnectionstring_test.go @@ -5,16 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = `Endpoint=https://trufflesecurity.azconfig.io;Id=u+De;Secret=80DtxZkndXpM2mV2J1JjX2vL1x4gm1hHn8Y3JeFJ4N0PPLSO5D70JQQJ99BBAC1i4FpQkb5wAAACAAZC26dr` - invalidPattern = `Endpoint=https://trufflesecurity.azconfig.io;Secret=80DtxZkndXpMTmV2J3JjX2vL1x4gm1hHn8Y3KeFV4N0PPLSO5D70JQQJ79BBAC1i4FpRkb5wAAACAAZC26dr` -) - func TestAzureAppConfigConnectionString_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -26,12 +22,26 @@ func TestAzureAppConfigConnectionString_Pattern(t *testing.T) { }{ { name: "valid pattern", - input: validPattern, + input: `Endpoint=https://trufflesecurity.azconfig.io;Id=u+De;Secret=80DtxZkndXpM2mV2J1JjX2vL1x4gm1hHn8Y3JeFJ4N0PPLSO5D70JQQJ99BBAC1i4FpQkb5wAAACAAZC26dr`, want: []string{"Endpoint=https://trufflesecurity.azconfig.io;Id=u+De;Secret=80DtxZkndXpM2mV2J1JjX2vL1x4gm1hHn8Y3JeFJ4N0PPLSO5D70JQQJ99BBAC1i4FpQkb5wAAACAAZC26dr"}, }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {connectionstring} + {AQAAABAAA Endpoint=https://iTHzRfnepCddRiYoBbPj-drVzUjwTNduwb3EUOTsuSAgg1e83Q7bw.azconfig.io;Id=eO04L+/m9rYn;Secret=G4jQ3GmcsYqlLkkG8uoIVbx08PZIJSdfB/7} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"Endpoint=https://iTHzRfnepCddRiYoBbPj-drVzUjwTNduwb3EUOTsuSAgg1e83Q7bw.azconfig.io;Id=eO04L+/m9rYn;Secret=G4jQ3GmcsYqlLkkG8uoIVbx08PZIJSdfB/7"}, + }, { name: "invalid pattern", - input: invalidPattern, + input: `Endpoint=https://trufflesecurity.azconfig.io;Secret=80DtxZkndXpMTmV2J3JjX2vL1x4gm1hHn8Y3KeFV4N0PPLSO5D70JQQJ79BBAC1i4FpRkb5wAAACAAZC26dr`, want: nil, }, } @@ -40,22 +50,15 @@ func TestAzureAppConfigConnectionString_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +70,7 @@ func TestAzureAppConfigConnectionString_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azurecontainerregistry/azurecontainerregistry_test.go b/pkg/detectors/azurecontainerregistry/azurecontainerregistry_test.go index b752b6d18..ea25cfd3d 100644 --- a/pkg/detectors/azurecontainerregistry/azurecontainerregistry_test.go +++ b/pkg/detectors/azurecontainerregistry/azurecontainerregistry_test.go @@ -5,19 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - invalidPattern = ` - azure: - url: http://invalid.azurecr.io.azure.com - secret: BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/+2Ytxc1hDq1m/ - ` -) - func TestAzureContainerRegistry_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -30,28 +23,27 @@ func TestAzureContainerRegistry_Pattern(t *testing.T) { { name: "pwd", input: `source storage.env - -ACR=smpldev.azurecr.io -ACRUSER=smpldev -ACRPWD=Cw8xeDNK6Bub3p61aq5ij/TiVvtBicpTj5rverVezj+ACRBPkEcx -CONTAINER=storage-svc:latest`, + ACR=smpldev.azurecr.io + ACRUSER=smpldev + ACRPWD=Cw8xeDNK6Bub3p61aq5ij/TiVvtBicpTj5rverVezj+ACRBPkEcx + CONTAINER=storage-svc:latest`, want: []string{`{"username":"smpldev","password":"Cw8xeDNK6Bub3p61aq5ij/TiVvtBicpTj5rverVezj+ACRBPkEcx"}`}, }, { name: "password", input: ` - name: Deploy to ARC - uses: azure/docker-login@v1 - with: - login-server: crmshopacr.azurecr.io - username: crmshopacr - password: o9uXSjWlUdRwAeGP2xGSfGy+25vetsONo3Mq13fksa+ACRBXyFsY - - run: |`, + uses: azure/docker-login@v1 + with: + login-server: crmshopacr.azurecr.io + username: crmshopacr + password: o9uXSjWlUdRwAeGP2xGSfGy+25vetsONo3Mq13fksa+ACRBXyFsY + - run: |`, want: []string{`{"username":"crmshopacr","password":"o9uXSjWlUdRwAeGP2xGSfGy+25vetsONo3Mq13fksa+ACRBXyFsY"}`}, }, { name: "docker cli login", input: `docker login dvacr00.azurecr.io -u dvacr00 -p Ljc+1lq0U0+c3jHlMHxSxAhCipKt6zU43HfMle/Ymj+ACRAKcPHy -docker push dvacr00.azurecr.io/foo-alpine:3.18`, + docker push dvacr00.azurecr.io/foo-alpine:3.18`, want: []string{`{"username":"dvacr00","password":"Ljc+1lq0U0+c3jHlMHxSxAhCipKt6zU43HfMle/Ymj+ACRAKcPHy"}`}, }, { @@ -62,16 +54,15 @@ docker push dvacr00.azurecr.io/foo-alpine:3.18`, { name: "README", input: `# AZURE-CICD-Deployment-with-Github-Actions + ## Save pass: -## Save pass: - -s3cEZKH3yytiVnJ3h+eI3qhhzf9l1vNwEi1+q+WGdd+ACRCZ7JD6 + s3cEZKH3yytiVnJ3h+eI3qhhzf9l1vNwEi1+q+WGdd+ACRCZ7JD6 -## Run from terminal: + ## Run from terminal: -docker build -t testapp.azurecr.io/chicken:latest . -`, + docker build -t testapp.azurecr.io/chicken:latest . + `, want: []string{`{"username":"testapp","password":"s3cEZKH3yytiVnJ3h+eI3qhhzf9l1vNwEi1+q+WGdd+ACRCZ7JD6"}`}, }, // TODO: @@ -85,9 +76,13 @@ docker build -t testapp.azurecr.io/chicken:latest . // input: ``, // want: []string{}, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + azure: + url: http://invalid.azurecr.io.azure.com + secret: BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/+2Ytxc1hDq1m/ + `, + want: nil, }, } @@ -95,22 +90,15 @@ docker build -t testapp.azurecr.io/chicken:latest . t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -122,6 +110,7 @@ docker build -t testapp.azurecr.io/chicken:latest . actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azuredevopspersonalaccesstoken/azuredevopspersonalaccesstoken_test.go b/pkg/detectors/azuredevopspersonalaccesstoken/azuredevopspersonalaccesstoken_test.go index b19ef9de3..282461675 100644 --- a/pkg/detectors/azuredevopspersonalaccesstoken/azuredevopspersonalaccesstoken_test.go +++ b/pkg/detectors/azuredevopspersonalaccesstoken/azuredevopspersonalaccesstoken_test.go @@ -5,24 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - azure: - azure_key: uie5tff7m5h5lqnqjhaltetqli90a08p6dhv9rn59uo30jgzw8un - azure_org_id: WOkQXnjSxCyioEJRa8R6J39cN4Xfyy8CWl1BZksHYsevxVBFzG - ` - invalidPattern = ` - azure: - azure_key: uie5tff7m5H5lqnqjhaltetqli90a08p6dhv9rn59uo30jgzw8un - azure_org_id: LOKi - ` -) - func TestAzureDevopsPersonalAccessToken_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,14 +21,39 @@ func TestAzureDevopsPersonalAccessToken_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"uie5tff7m5h5lqnqjhaltetqli90a08p6dhv9rn59uo30jgzw8unWOkQXnjSxCyioEJRa8R6J39cN4Xfyy8CWl1BZksHYsevxVBFzG"}, + name: "valid pattern", + input: ` + azure: + azure_key: uie5tff7m5h5lqnqjhaltetqli90a08p6dhv9rn59uo30jgzw8un + azure_org_id: WOkQXnjSxCyioEJRa8R6J39cN4Xfyy8CWl1BZksHYsevxVBFzG + `, + want: []string{"uie5tff7m5h5lqnqjhaltetqli90a08p6dhv9rn59uo30jgzw8unWOkQXnjSxCyioEJRa8R6J39cN4Xfyy8CWl1BZksHYsevxVBFzG"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {azure dlMR9GIBfqCgAPr8qfkBa072OfaP6NbBhCwkPBX0cuHd} + {azure AQAAABAAA h0wpgbusyba8acyaec1uxxcbxlucgr490c6nvrvd8rylfocwkpg5} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{ + "h0wpgbusyba8acyaec1uxxcbxlucgr490c6nvrvd8rylfocwkpg5dlMR9GIBfqCgAPr8qfkBa072OfaP6NbBhCwkPBX0cuHd", + "h0wpgbusyba8acyaec1uxxcbxlucgr490c6nvrvd8rylfocwkpg5AQAAABAAA", + }, + }, + { + name: "invalid pattern", + input: ` + azure: + azure_key: uie5tff7m5H5lqnqjhaltetqli90a08p6dhv9rn59uo30jgzw8un + azure_org_id: LOKi + `, + want: nil, }, } @@ -48,22 +61,15 @@ func TestAzureDevopsPersonalAccessToken_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +81,7 @@ func TestAzureDevopsPersonalAccessToken_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azuredirectmanagementkey/azuredirectmanagementkey_test.go b/pkg/detectors/azuredirectmanagementkey/azuredirectmanagementkey_test.go index 4185c7ecf..188585234 100644 --- a/pkg/detectors/azuredirectmanagementkey/azuredirectmanagementkey_test.go +++ b/pkg/detectors/azuredirectmanagementkey/azuredirectmanagementkey_test.go @@ -5,22 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - AZURE_MANGEMENT_API_KEY=UJh1Wn7txjls2GPK1YxO9+3tpqQffSfxb+97PmT8j3cSQoXvGa74lCKpBqPeppTHCharbaMeKqKs/H4gA/go1w== - AZURE_MANAGEMENT_API_URL=https://trufflesecuritytest.management.azure-api.net - ` - invalidPattern = ` - AZURE_MANGEMENT_API_KEY=UJh1Wn7txjls2GPK1YxO9+3tpqQffSfxb+97PmT8j3cSQoXvGa74lCKp - AZURE_MANAGEMENT_API_URL=https://trufflesecuritytest.management.azure-api.net - ` -) - func TestAzureDirectManagementAPIKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -31,14 +21,34 @@ func TestAzureDirectManagementAPIKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"https://trufflesecuritytest.management.azure-api.net:UJh1Wn7txjls2GPK1YxO9+3tpqQffSfxb+97PmT8j3cSQoXvGa74lCKpBqPeppTHCharbaMeKqKs/H4gA/go1w=="}, + name: "valid pattern", + input: ` + AZURE_MANGEMENT_API_KEY=UJh1Wn7txjls2GPK1YxO9+3tpqQffSfxb+97PmT8j3cSQoXvGa74lCKpBqPeppTHCharbaMeKqKs/H4gA/go1w== + AZURE_MANAGEMENT_API_URL=https://trufflesecuritytest.management.azure-api.net + `, + want: []string{"https://trufflesecuritytest.management.azure-api.net:UJh1Wn7txjls2GPK1YxO9+3tpqQffSfxb+97PmT8j3cSQoXvGa74lCKpBqPeppTHCharbaMeKqKs/H4gA/go1w=="}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {https://0q66287uqx.management.azure-api.net} + {AQAAABAAA Ub4yMRDBBdEX/BNyNFM6i6Odj25TB0Zd1BRNx57ZeMGpqzkeokXheNpkkTBtvPQb692id65yc2xLKhZ183rg==} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"https://0q66287uqx.management.azure-api.net:Ub4yMRDBBdEX/BNyNFM6i6Odj25TB0Zd1BRNx57ZeMGpqzkeokXheNpkkTBtvPQb692id65yc2xLKhZ183rg=="}, + }, + { + name: "invalid pattern", + input: ` + AZURE_MANGEMENT_API_KEY=UJh1Wn7txjls2GPK1YxO9+3tpqQffSfxb+97PmT8j3cSQoXvGa74lCKp + AZURE_MANAGEMENT_API_URL=https://trufflesecuritytest.management.azure-api.net + `, + want: nil, }, } @@ -46,22 +56,15 @@ func TestAzureDirectManagementAPIKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -73,6 +76,7 @@ func TestAzureDirectManagementAPIKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azurefunctionkey/azurefunctionkey_test.go b/pkg/detectors/azurefunctionkey/azurefunctionkey_test.go index f284a28d7..22abd6cbd 100644 --- a/pkg/detectors/azurefunctionkey/azurefunctionkey_test.go +++ b/pkg/detectors/azurefunctionkey/azurefunctionkey_test.go @@ -5,24 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - azure: - azureURL: https://z1dUSi5T.azurewebsites.net/api/W8anB5J4uQi-v3Dcd6p7ySE0E - azureFunctionkey: B8sm0KyfL1y8vPH3IDTdefevHBCGK33-= - ` - invalidPattern = ` - azure: - azureURL: http://invalid.azurecr.io.azure.com - azureFunctionkey: BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/+2Ytxc1hDq1m/ - ` -) - func TestAzureFunctionKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,17 +21,39 @@ func TestAzureFunctionKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, + name: "valid pattern", + input: ` + azure: + azureURL: https://z1dUSi5T.azurewebsites.net/api/W8anB5J4uQi-v3Dcd6p7ySE0E + azureFunctionkey: B8sm0KyfL1y8vPH3IDTdefevHBCGK33-= + `, want: []string{ "azurewebsites.net/api/W8anB5J4uQi-v3Dcd6p7ySE0Ehttps://z1dUSi5T.azurewebsites.net/api/W8anB5J4uQi-v3Dcd6p7ySE0E", "B8sm0KyfL1y8vPH3IDTdefevHBCGK33https://z1dUSi5T.azurewebsites.net/api/W8anB5J4uQi-v3Dcd6p7ySE0E", }, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {https://yaeuxPA9-H.azurewebsites.net/api/Hwy5K} + {azure AQAAABAAA Ijbql3DKRyIZNQIddzCYKICr} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"Ijbql3DKRyIZNQIddzCYKICrhttps://yaeuxPA9-H.azurewebsites.net/api/Hwy5K"}, + }, + { + name: "invalid pattern", + input: ` + azure: + azureURL: http://invalid.azurecr.io.azure.com + azureFunctionkey: BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/+2Ytxc1hDq1m/ + `, + want: nil, }, } @@ -51,22 +61,15 @@ func TestAzureFunctionKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -78,6 +81,7 @@ func TestAzureFunctionKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azuresastoken/azuresastoken_test.go b/pkg/detectors/azuresastoken/azuresastoken_test.go index 62c8330a2..fec99debd 100644 --- a/pkg/detectors/azuresastoken/azuresastoken_test.go +++ b/pkg/detectors/azuresastoken/azuresastoken_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -89,22 +90,15 @@ func TestAzureSASToken_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -116,6 +110,7 @@ func TestAzureSASToken_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azuresearchadminkey/azuresearchadminkey_test.go b/pkg/detectors/azuresearchadminkey/azuresearchadminkey_test.go index aeb5b2094..e2dc17271 100644 --- a/pkg/detectors/azuresearchadminkey/azuresearchadminkey_test.go +++ b/pkg/detectors/azuresearchadminkey/azuresearchadminkey_test.go @@ -5,24 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - azure: - azureKey: wRRPyhjv8m6JGRujUUrPKa8d3rJ0mrGAxhmqf3A68OgZmlWUJyma - azureService: TestingService01 - ` - invalidPattern = ` - azure: - Key: wRRPyhjv8m6JGRujUUr-PK#a8d3rJ0mrGAxhmqf3A68OgZmlWUJyma - Service: TS01 - ` -) - func TestAzureSearchAdminKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -33,14 +21,39 @@ func TestAzureSearchAdminKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"wRRPyhjv8m6JGRujUUrPKa8d3rJ0mrGAxhmqf3A68OgZmlWUJymaTestingService01", "wRRPyhjv8m6JGRujUUrPKa8d3rJ0mrGAxhmqf3A68OgZmlWUJymaazureKey"}, + name: "valid pattern", + input: ` + azure: + azureKey: wRRPyhjv8m6JGRujUUrPKa8d3rJ0mrGAxhmqf3A68OgZmlWUJyma + azureService: TestingService01 + `, + want: []string{"wRRPyhjv8m6JGRujUUrPKa8d3rJ0mrGAxhmqf3A68OgZmlWUJymaTestingService01", "wRRPyhjv8m6JGRujUUrPKa8d3rJ0mrGAxhmqf3A68OgZmlWUJymaazureKey"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {azure bhIIhGTLlW7gLxy4rM93gLPaPFwdRajJX} + {azure AQAAABAAA Pntv3pDD31oczaYT99OanBBZyYlnKGUpQb4WEFnK6uUsKiR0Mc09} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{ + "Pntv3pDD31oczaYT99OanBBZyYlnKGUpQb4WEFnK6uUsKiR0Mc09bhIIhGTLlW7gLxy4rM93gLPaPFwdRajJX", + "Pntv3pDD31oczaYT99OanBBZyYlnKGUpQb4WEFnK6uUsKiR0Mc09AQAAABAAA", + }, + }, + { + name: "invalid pattern", + input: ` + azure: + Key: wRRPyhjv8m6JGRujUUr-PK#a8d3rJ0mrGAxhmqf3A68OgZmlWUJyma + Service: TS01 + `, + want: nil, }, } @@ -48,22 +61,15 @@ func TestAzureSearchAdminKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +81,7 @@ func TestAzureSearchAdminKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/azuresearchquerykey/azuresearchquerykey_test.go b/pkg/detectors/azuresearchquerykey/azuresearchquerykey_test.go index 3af2254ec..e0651ecda 100644 --- a/pkg/detectors/azuresearchquerykey/azuresearchquerykey_test.go +++ b/pkg/detectors/azuresearchquerykey/azuresearchquerykey_test.go @@ -5,25 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - azure: - azure_url: https://tzyexx2ktdfhha8w1cktqzbrgv37ywtu.search.windows.net/indexes/n81wg81jogjfq93cyxfi67vy2g7vwlcqfgi - azure_key: OKalbM5EBt5hloqU46phTUCZqvNAlZ4S2Jd2gFUCOQ3HG0vQ2uEp - - ` - invalidPattern = ` - azure: - url: http://invalid.azurecr.io.azure.com - azure_key: BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/+2Ytxc1hDq1m/ - ` -) - func TestAzureSearchQueryKey_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -34,14 +21,36 @@ func TestAzureSearchQueryKey_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"OKalbM5EBt5hloqU46phTUCZqvNAlZ4S2Jd2gFUCOQ3HG0vQ2uEphttps://tzyexx2ktdfhha8w1cktqzbrgv37ywtu.search.windows.net/indexes/n81wg81jogjfq93cyxfi67vy2g7vwlcqfgi"}, + name: "valid pattern", + input: ` + azure: + azure_url: https://tzyexx2ktdfhha8w1cktqzbrgv37ywtu.search.windows.net/indexes/n81wg81jogjfq93cyxfi67vy2g7vwlcqfgi + azure_key: OKalbM5EBt5hloqU46phTUCZqvNAlZ4S2Jd2gFUCOQ3HG0vQ2uEp + `, + want: []string{"OKalbM5EBt5hloqU46phTUCZqvNAlZ4S2Jd2gFUCOQ3HG0vQ2uEphttps://tzyexx2ktdfhha8w1cktqzbrgv37ywtu.search.windows.net/indexes/n81wg81jogjfq93cyxfi67vy2g7vwlcqfgi"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {azure https://w3fsj4c22rdn7mhkf1yxbt7orrvzd720a.search.windows.net/indexes/5934qi40xctuhmzba7ty} + {azure AQAAABAAA C3idqCYnGa1cTx7iEFJ684QCbSDcEz1jq4s7iRxDDPWYKoK3h3Lr} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"C3idqCYnGa1cTx7iEFJ684QCbSDcEz1jq4s7iRxDDPWYKoK3h3Lrhttps://w3fsj4c22rdn7mhkf1yxbt7orrvzd720a.search.windows.net/indexes/5934qi40xctuhmzba7ty"}, + }, + { + name: "invalid pattern", + input: ` + azure: + url: http://invalid.azurecr.io.azure.com + azure_key: BXIMbhBlC3=5hIbqCEKvq7op!V2ZfO0XWbcnasZmPm/AJfQqdcnt/+2Ytxc1hDq1m/ + `, + want: nil, }, } @@ -49,22 +58,15 @@ func TestAzureSearchQueryKey_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -76,6 +78,7 @@ func TestAzureSearchQueryKey_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bannerbear/v1/bannerbear_test.go b/pkg/detectors/bannerbear/v1/bannerbear_test.go index 4cac36af2..009862310 100644 --- a/pkg/detectors/bannerbear/v1/bannerbear_test.go +++ b/pkg/detectors/bannerbear/v1/bannerbear_test.go @@ -2,47 +2,15 @@ package bannerbear import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "yvxpthLIcYpZweFpPOVeCOtt" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - bannerBearToken := "Bearer yvxpthLIcYpZweFpPOVeCOtt" - req.Header.Set("Authorization", bannerBearToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "yvxpthLIcYpZweFpPOVeCOtot" -) - func TestBannerBear_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBannerBear_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bannerbear credentials: %s", validPattern), - want: []string{"yvxpthLIcYpZweFpPOVeCOtt"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bannerBearToken := "Bearer yvxpthLIcYpZweFpPOVeCOtt" + req.Header.Set("Authorization", bannerBearToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"yvxpthLIcYpZweFpPOVeCOtt"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"yvxpthLIcYpZweFpPOVeCOtt"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bannerbear} + {bannerbear AQAAABAAA Y5UbXOT1Xh1ZOCxztUvGqltt} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"Y5UbXOT1Xh1ZOCxztUvGqltt"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bannerbear credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bannerBearToken := "Bearer yvxpthLIcYpZweFpPOVeCOtot" + req.Header.Set("Authorization", bannerBearToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBannerBear_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBannerBear_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bannerbear/v2/bannerbear_test.go b/pkg/detectors/bannerbear/v2/bannerbear_test.go index 4ac8506d4..f75714a71 100644 --- a/pkg/detectors/bannerbear/v2/bannerbear_test.go +++ b/pkg/detectors/bannerbear/v2/bannerbear_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -20,19 +21,66 @@ func TestBannerBear_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: "bannerbear credentials: bb_pr_abcdc2b40ef44abcd8cbf3739aabcd", - want: []string{"bb_pr_abcdc2b40ef44abcd8cbf3739aabcd"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bannerBearToken := "Bearer bb_pr_abcdc2b40ef44abcd8cbf3739aabcd" + req.Header.Set("Authorization", bannerBearToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"bb_pr_abcdc2b40ef44abcd8cbf3739aabcd"}, }, { - name: "valid pattern - complex", - input: "bannerbear credentials: ajahf ajkahfkjah fka bb_pr_abcdc2b40ef44abcd8cbf3739aacba adlkajflaihflahdljajfla", - want: []string{"bb_pr_abcdc2b40ef44abcd8cbf3739aacba"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {} + {AQAAABAAA bb_ma_900063380acef4c7e24c5bcee8af22} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"bb_ma_900063380acef4c7e24c5bcee8af22"}, }, { - name: "invalid pattern", - input: "bannerbear credentials: bb_pr_abcd", - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bannerBearToken := "Bearer bb_ma_abcdc2b40ef44abcd8cbf3739aabcq" + req.Header.Set("Authorization", bannerBearToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -40,22 +88,15 @@ func TestBannerBear_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -67,6 +108,7 @@ func TestBannerBear_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/baremetrics/baremetrics_test.go b/pkg/detectors/baremetrics/baremetrics_test.go index 89206d7d9..71ae28b90 100644 --- a/pkg/detectors/baremetrics/baremetrics_test.go +++ b/pkg/detectors/baremetrics/baremetrics_test.go @@ -2,47 +2,15 @@ package baremetrics import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "sk_nGDJWCkPiFAKE5XFTzUUA" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - baremetricsToken := "Bearer sk_nGDJWCkPiFAKE5XFTzUUA" - req.Header.Set("Authorization", baremetricsToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "sk_nGDJWC_io8Q025XFTzUUA" -) - func TestBareMetrics_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBareMetrics_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("baremetrics credentials: %s", validPattern), - want: []string{"sk_nGDJWCkPiFAKE5XFTzUUA"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + baremetricsToken := "Bearer sk_nGDJWCkPiFAKE5XFTzUUA" + req.Header.Set("Authorization", baremetricsToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"sk_nGDJWCkPiFAKE5XFTzUUA"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"sk_nGDJWCkPiFAKE5XFTzUUA"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {baremetrics} + {baremetrics AQAAABAAA lk_JcWYJEi80ZzQA1nRXD} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"lk_JcWYJEi80ZzQA1nRXD"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("baremetrics credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + baremetricsToken := "Bearer sk_nGDJWC_io8Q025XFTzUUA" + req.Header.Set("Authorization", baremetricsToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBareMetrics_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBareMetrics_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/beamer/beamer_test.go b/pkg/detectors/beamer/beamer_test.go index aa40186d8..2a9b710f0 100644 --- a/pkg/detectors/beamer/beamer_test.go +++ b/pkg/detectors/beamer/beamer_test.go @@ -2,46 +2,15 @@ package beamer import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "DyVdf7+cAXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO=" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - req.Header.Set("Beamer-Api-Key", "DyVdf7+cAXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO=") - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "DyVdf7%c^AXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO" -) - func TestBeamer_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -52,19 +21,64 @@ func TestBeamer_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("beamer credentials: %s", validPattern), - want: []string{"DyVdf7+cAXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO="}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + req.Header.Set("Beamer-Api-Key", "DyVdf7+cAXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO=") + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"DyVdf7+cAXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO="}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"DyVdf7+cAXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO="}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {beamer} + {beamer AQAAABAAA _FXYx2kyyNv6n_CBb9LrMHZPXa_S8iaj89zYn9mICmkB4=} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"_FXYx2kyyNv6n_CBb9LrMHZPXa_S8iaj89zYn9mICmkB4="}, }, { - name: "invalid pattern", - input: fmt.Sprintf("beamer credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + req.Header.Set("Beamer-Api-Key", "DyVdf7%c^AXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO") + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -72,22 +86,15 @@ func TestBeamer_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -99,6 +106,7 @@ func TestBeamer_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/beebole/beebole_test.go b/pkg/detectors/beebole/beebole_test.go index a68222075..b9f668f06 100644 --- a/pkg/detectors/beebole/beebole_test.go +++ b/pkg/detectors/beebole/beebole_test.go @@ -2,47 +2,15 @@ package beebole import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "bn6htprmfpukfalts4muwalxh9j15ucvnrfdme8t" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - beeboleAuth := b51rul64exy5yz0gupfm0bbh0b5efg2sc6kex9rk - req.Header.Set("Authorization", "Basic " + beeboleAuth) // beebole authorization header - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "DyVdf7%c^AXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO" -) - func TestBeeBole_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBeeBole_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("beebole credentials: %s", validPattern), - want: []string{"bn6htprmfpukfalts4muwalxh9j15ucvnrfdme8t"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + beeboleAuth := bn6htprmfpukfalts4muwalxh9j15ucvnrfdme8t + req.Header.Set("Authorization", "Basic " + beeboleAuth) // beebole authorization header + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"bn6htprmfpukfalts4muwalxh9j15ucvnrfdme8t"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"b51rul64exy5yz0gupfm0bbh0b5efg2sc6kex9rk"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {beebole} + {beebole AQAAABAAA rtwtgvvvekkik48t08tvf659hvyb5w8u4xnueh3u} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"rtwtgvvvekkik48t08tvf659hvyb5w8u4xnueh3u"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("beebole credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + beeboleAuth := DyVdf7%c^AXw4MH9gT1CPotU31RMl__aLKbrABRWvT7TyO + req.Header.Set("Authorization", "Basic " + beeboleAuth) // beebole authorization header + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBeeBole_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBeeBole_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/besnappy/besnappy_test.go b/pkg/detectors/besnappy/besnappy_test.go index 1e8d1da3e..0ad239321 100644 --- a/pkg/detectors/besnappy/besnappy_test.go +++ b/pkg/detectors/besnappy/besnappy_test.go @@ -2,47 +2,15 @@ package besnappy import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "f58c5d37d7876d32cfdd823f8fe4ded364a8d483b5dbfadcc55ad801b3be8523" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - beSnappyToken := f58c5d37d7876d32cfdd823f8fe4ded364a8d483b5dbfadcc55ad801b3be8523 - req.Header.Set("Authorization", "Basic " + beSnappyToken) // authorization header - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "f58c5d37d7876d32cf__f8fe4ded364a8d483b5db+adcc55ad801b3be8523" -) - func TestBeSnappy_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBeSnappy_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("besnappy credentials: %s", validPattern), - want: []string{"f58c5d37d7876d32cfdd823f8fe4ded364a8d483b5dbfadcc55ad801b3be8523"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + beSnappyToken := f58c5d37d7876d32cfdd823f8fe4ded364a8d483b5dbfadcc55ad801b3be8523 + req.Header.Set("Authorization", "Basic " + beSnappyToken) // authorization header + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"f58c5d37d7876d32cfdd823f8fe4ded364a8d483b5dbfadcc55ad801b3be8523"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"f58c5d37d7876d32cfdd823f8fe4ded364a8d483b5dbfadcc55ad801b3be8523"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {besnappy} + {besnappy AQAAABAAA da5a2e65d83a40d6cebaac60ef01803f8c1a612baa428992ad4c7301df2759ba} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"da5a2e65d83a40d6cebaac60ef01803f8c1a612baa428992ad4c7301df2759ba"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("besnappy credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte("{}"))) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + beSnappyToken := f58c5d37d7876d32cf__f8fe4ded364a8d483b5db+adcc55ad801b3be8523 + req.Header.Set("Authorization", "Basic " + beSnappyToken) // authorization header + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBeSnappy_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBeSnappy_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/besttime/besttime_test.go b/pkg/detectors/besttime/besttime_test.go index abc930ef2..3af4f58f1 100644 --- a/pkg/detectors/besttime/besttime_test.go +++ b/pkg/detectors/besttime/besttime_test.go @@ -2,44 +2,15 @@ package besttime import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "pri_099889f14d114dfaae476569b395eade" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/besttime/keys/pri_099889f14d114dfaae476569b395eade" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "4K1WTb2ysVeg^jHD*wtwhH68K9MuOjiTtXQCS" -) - func TestBestTime_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -50,19 +21,60 @@ func TestBestTime_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("besttime credentials: %s", validPattern), - want: []string{"pri_099889f14d114dfaae476569b395eade"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/besttime/keys/pri_099889f14d114dfaae476569b395eade" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"pri_099889f14d114dfaae476569b395eade"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"pri_099889f14d114dfaae476569b395eade"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {besttime} + {besttime AQAAABAAA pri_cffe0fa1b281feeb01216ec73e149b00} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"pri_cffe0fa1b281feeb01216ec73e149b00"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("besttime credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/besttime/keys/4K1WTb2ysVeg^jHD*wtwhH68K9MuOjiTtXQCS" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -70,22 +82,15 @@ func TestBestTime_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -97,6 +102,7 @@ func TestBestTime_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/betterstack/betterstack_test.go b/pkg/detectors/betterstack/betterstack_test.go index 7c1451442..45ff9579b 100644 --- a/pkg/detectors/betterstack/betterstack_test.go +++ b/pkg/detectors/betterstack/betterstack_test.go @@ -2,47 +2,15 @@ package betterstack import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "ntJD0ER8QpuT0O1WqsclApO2" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - req.Header.Set("Authorization", "Bearer " + getbetterStackToken()) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - func getBetterStackToken() string{ return "ntJD0ER8QpuT0O1WqsclApO2" } - ` - invalidPattern = "DyntJD0ER8QpuT0O1WqsclApO2" -) - func TestBetterStack_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBetterStack_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("betterstack credentials: %s", validPattern), - want: []string{"ntJD0ER8QpuT0O1WqsclApO2"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + req.Header.Set("Authorization", "Bearer " + getbetterStackToken()) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + func getBetterStackToken() string{ return "ntJD0ER8QpuT0O1WqsclApO2" } + `, + want: []string{"ntJD0ER8QpuT0O1WqsclApO2"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"ntJD0ER8QpuT0O1WqsclApO2"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {betterstack} + {betterstack AQAAABAAA RtSmhl4GkEcFS84Oyi0zlYbE} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"RtSmhl4GkEcFS84Oyi0zlYbE"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("betterstack credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + req.Header.Set("Authorization", "Bearer " + getbetterStackToken()) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + func getBetterStackToken() string{ return "DyntJD0ER8QpuT0O1WqsclApO2" } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBetterStack_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBetterStack_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/billomat/billomat_test.go b/pkg/detectors/billomat/billomat_test.go index f011ff686..0aa00263d 100644 --- a/pkg/detectors/billomat/billomat_test.go +++ b/pkg/detectors/billomat/billomat_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -50,9 +51,28 @@ func TestBilloMat_Pattern(t *testing.T) { "c09761f99f39f79ae28eaaf8df20d7c9truffletest", }, }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {billomat m2o8fqf8} + {billomat AQAAABAAA 36a584c280b5b617e8eb25dae6b64d63} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"36a584c280b5b617e8eb25dae6b64d63m2o8fqf8"}, + }, { name: "invalid pattern", input: ` + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } req.Header.Set("X-BillomatApiKey", "c09761h99f39f79ae28eaaf8df20d7c9") billomatID := truffle-test `, @@ -64,22 +84,15 @@ func TestBilloMat_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -91,6 +104,7 @@ func TestBilloMat_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bingsubscriptionkey/bingsubscriptionkey_test.go b/pkg/detectors/bingsubscriptionkey/bingsubscriptionkey_test.go index ce4fa53d2..52a8a61d1 100644 --- a/pkg/detectors/bingsubscriptionkey/bingsubscriptionkey_test.go +++ b/pkg/detectors/bingsubscriptionkey/bingsubscriptionkey_test.go @@ -2,10 +2,13 @@ package bingsubscriptionkey import ( "context" + "testing" + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" - "testing" ) func TestBingsubscriptionkey_Pattern(t *testing.T) { @@ -17,20 +20,66 @@ func TestBingsubscriptionkey_Pattern(t *testing.T) { want []string }{ { - name: "typical pattern", - input: "bing_subscription_key=89017d414ed64edb9c776d4a52102b9a", - want: []string{"89017d414ed64edb9c776d4a52102b9a"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.net/v2/api" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // set bing subscription key + bingKey := "89017d414ed64edb9c776d4a52102b9a" + req.Header.Set("Ocp-Apim-Subscription-Key", bingKey) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + }`, + want: []string{"89017d414ed64edb9c776d4a52102b9a"}, }, { - name: "finds all matches", - input: `bing_subscription_key1=89017d414ed64edb9c776d4a52102b9b' -bing_subscription_key2=89017d414ed64edb9c776d4a52102b9c`, - want: []string{"89017d414ed64edb9c776d4a52102b9b", "89017d414ed64edb9c776d4a52102b9c"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bing} + {bing AQAAABAAA dB963b030A1DafB02d8299F04A00a306} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"dB963b030A1DafB02d8299F04A00a306"}, }, { - name: "invalid pattern", - input: "bing_subscription_key=89017d414ed64edb9c776d4a52102b9", - want: []string{}, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.net/v2/api" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // set bing subscription key + bingKey := "89017d414ed64edb9c776d4J52102b9" + req.Header.Set("Ocp-Apim-Subscription-Key", bingKey) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + }`, + want: []string{}, }, } @@ -38,22 +87,15 @@ bing_subscription_key2=89017d414ed64edb9c776d4a52102b9c`, t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -65,6 +107,7 @@ bing_subscription_key2=89017d414ed64edb9c776d4a52102b9c`, actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bitbar/bitbar_test.go b/pkg/detectors/bitbar/bitbar_test.go index 17201c017..a598ef4aa 100644 --- a/pkg/detectors/bitbar/bitbar_test.go +++ b/pkg/detectors/bitbar/bitbar_test.go @@ -2,50 +2,15 @@ package bitbar import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "64pq66z15thg8fh3acd00l35lpyg7c82" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - bitBarSecret := os.GetEnv("BITBAR_SECRET") - if bitBarSecret == ""{ - bitBarSecret = "64pq66z15thg8fh3acd00l35lpyg7c82" - } - req.Header.Set("Authorization", "Basic " + bitBarSecret) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "DyV64pq66z15thg8fh3&cd00l35lpyg7c82$" -) - func TestBitBar_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -56,19 +21,72 @@ func TestBitBar_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bitbar credentials: %s", validPattern), - want: []string{"64pq66z15thg8fh3acd00l35lpyg7c82"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bitBarSecret := os.GetEnv("BITBAR_SECRET") + if bitBarSecret == ""{ + bitBarSecret = "64pq66z15thg8fh3acd00l35lpyg7c82" + } + req.Header.Set("Authorization", "Basic " + bitBarSecret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"64pq66z15thg8fh3acd00l35lpyg7c82"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"64pq66z15thg8fh3acd00l35lpyg7c82"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bitbar} + {bitbar AQAAABAAA EJEpftl3MtqwEvE9nwiJhw2rWgjrhP1q} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"EJEpftl3MtqwEvE9nwiJhw2rWgjrhP1q"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bitbar credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bitBarSecret := os.GetEnv("BITBAR_SECRET") + if bitBarSecret == ""{ + bitBarSecret = "DyV64pq66z15thg8fh3&cd00l35lpyg7c82$" + } + req.Header.Set("Authorization", "Basic " + bitBarSecret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -76,22 +94,15 @@ func TestBitBar_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -103,6 +114,7 @@ func TestBitBar_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bitbucketapppassword/bitbucketapppassword_test.go b/pkg/detectors/bitbucketapppassword/bitbucketapppassword_test.go index abfa51a0f..b9fa2c213 100644 --- a/pkg/detectors/bitbucketapppassword/bitbucketapppassword_test.go +++ b/pkg/detectors/bitbucketapppassword/bitbucketapppassword_test.go @@ -5,18 +5,43 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" + "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) func TestBitbucketAppPassword_FromData(t *testing.T) { + d := Scanner{} + ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) + tests := []struct { name string input string want []string }{ { - name: "valid pair", - input: "myuser:ATBB123abcDEF456ghiJKL789mnoPQR", - want: []string{"myuser:ATBB123abcDEF456ghiJKL789mnoPQR"}, + name: "valid pair", + input: ` + [INFO] Sending request to the bitbucket API + [DEBUG] Using autodesk Key=myuser:ATBB123abcDEF456ghiJKL789mnoPQR + [INFO] Response received: 200 OK + `, + want: []string{"myuser:ATBB123abcDEF456ghiJKL789mnoPQR"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {} + {AQAAABAAA https://trufflesec:ATBBa9iO-tyg7u_op@bitbucket.org} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"trufflesec:ATBBa9iO-tyg7u_op"}, }, { name: "valid app password by itself (should not be found)", @@ -45,26 +70,38 @@ func TestBitbucketAppPassword_FromData(t *testing.T) { }, } - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - d := &Scanner{} - results, err := d.FromData(context.Background(), false, []byte(tc.input)) - if err != nil { - t.Fatalf("FromData() error = %v", err) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) + if len(matchedDetectors) == 0 { + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) + return } - got := make(map[string]struct{}) + results, err := d.FromData(context.Background(), false, []byte(test.input)) + require.NoError(t, err) + + if len(results) != len(test.want) { + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) + return + } + + actual := make(map[string]struct{}, len(results)) for _, r := range results { - got[string(r.Raw)] = struct{}{} + if len(r.RawV2) > 0 { + actual[string(r.RawV2)] = struct{}{} + } else { + actual[string(r.Raw)] = struct{}{} + } } - wantSet := make(map[string]struct{}) - for _, w := range tc.want { - wantSet[w] = struct{}{} + expected := make(map[string]struct{}, len(test.want)) + for _, v := range test.want { + expected[v] = struct{}{} } - if diff := cmp.Diff(wantSet, got); diff != "" { - t.Errorf("FromData() mismatch (-want +got):\n%s", diff) + if diff := cmp.Diff(expected, actual); diff != "" { + t.Errorf("%s diff: (-want +got)\n%s", test.name, diff) } }) } diff --git a/pkg/detectors/bitcoinaverage/bitcoinaverage_test.go b/pkg/detectors/bitcoinaverage/bitcoinaverage_test.go index 38c906e1d..d92960ca6 100644 --- a/pkg/detectors/bitcoinaverage/bitcoinaverage_test.go +++ b/pkg/detectors/bitcoinaverage/bitcoinaverage_test.go @@ -2,50 +2,15 @@ package bitcoinaverage import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "zt7WwXWk7MYMNB3l2QdtB5itl9uvfhJ8s6h0hibid5E" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - secret := os.GetEnv("BITCOINAVERAGE") - if secret == ""{ - secret = "zt7WwXWk7MYMNB3l2QdtB5itl9uvfhJ8s6h0hibid5E" // bitcoin average secret - } - req.Header.Set("x-ba-key", secret) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "DyV64pq66z15thg8fh3&cd00l35lpyg7c82$" -) - func TestBitCoinAverage_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -56,19 +21,74 @@ func TestBitCoinAverage_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bitcoinaverage credentials: %s", validPattern), - want: []string{"zt7WwXWk7MYMNB3l2QdtB5itl9uvfhJ8s6h0hibid5E"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + secret := os.GetEnv("BITCOINAVERAGE") + if secret == ""{ + // bitcoinaverage secret + secret = "WZizqeWvRnhZmFlpc5pMc92NP1Du19wxxpd5zjsYY8F" + } + req.Header.Set("x-ba-key", secret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"WZizqeWvRnhZmFlpc5pMc92NP1Du19wxxpd5zjsYY8F"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"zt7WwXWk7MYMNB3l2QdtB5itl9uvfhJ8s6h0hibid5E"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bitcoinaverage} + {bitcoinaverage AQAAABAAA gVXtVKIj5CO3b0F12XjibnE2TvwS5rL5nJ0kQ2NZkso} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"gVXtVKIj5CO3b0F12XjibnE2TvwS5rL5nJ0kQ2NZkso"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bitcoinaverage credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + secret := os.GetEnv("BITCOINAVERAGE") + if secret == ""{ + // bitcoinaverage secret + secret = "DyV64pq66z15thg8fh3&cd00l35lpyg7c82$" + } + req.Header.Set("x-ba-key", secret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -76,22 +96,15 @@ func TestBitCoinAverage_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -103,6 +116,7 @@ func TestBitCoinAverage_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bitfinex/bitfinex_test.go b/pkg/detectors/bitfinex/bitfinex_test.go index 1403b96ff..29202cb48 100644 --- a/pkg/detectors/bitfinex/bitfinex_test.go +++ b/pkg/detectors/bitfinex/bitfinex_test.go @@ -2,28 +2,15 @@ package bitfinex import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "bitfinexKey: HxfuG198amaeCcYkASkto5VuIO-oXcplDV6JZ7OIEQZ / bitfinexSecret: Pf3-3v989gPbJT54D3oDBiFZmJoLpWoTHGvF8xuSBPP" - complexPattern = ` - func main() { - bitfinexKey := "HxfuG198amaeCcYkASkto5VuIO-oXcplDV6JZ7OIEQZ" - bitfinexSecret := "Pf3-3v989gPbJT54D3oDBiFZmJoLpWoTHGvF8xuSBPP" - http.DefaultClient = client - c := rest.NewClientWithURL(*api).Credentials(key, secret) - } - ` - invalidPattern = "kASkto5VuIO%c^HxfuG198amaeCcYkASkto5VuIO" -) - func TestBitFinex_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -34,19 +21,45 @@ func TestBitFinex_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bitfinex credentials: %s", validPattern), - want: []string{"HxfuG198amaeCcYkASkto5VuIO-oXcplDV6JZ7OIEQZ", "Pf3-3v989gPbJT54D3oDBiFZmJoLpWoTHGvF8xuSBPP"}, + name: "valid pattern", + input: ` + func main() { + bitfinexKey := "HxfuG198amaeCcYkASkto5VuIO-oXcplDV6JZ7OIEQZ" + bitfinexSecret := "Pf3-3v989gPbJT54D3oDBiFZmJoLpWoTHGvF8xuSBPP" + http.DefaultClient = client + c := rest.NewClientWithURL(*api).Credentials(key, secret) + } + `, + want: []string{"HxfuG198amaeCcYkASkto5VuIO-oXcplDV6JZ7OIEQZ", "Pf3-3v989gPbJT54D3oDBiFZmJoLpWoTHGvF8xuSBPP"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"Pf3-3v989gPbJT54D3oDBiFZmJoLpWoTHGvF8xuSBPP", "HxfuG198amaeCcYkASkto5VuIO-oXcplDV6JZ7OIEQZ"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bitfinex bdiODwPukXLKUjSLvfeTlKVEwm89zqOhQ2a9chacKcr} + {bitfinex AQAAABAAA MTvK78juiZmddv3eEyoz1gqRwP89OHreiX6fnXkfbce} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{ + "bdiODwPukXLKUjSLvfeTlKVEwm89zqOhQ2a9chacKcr", + "MTvK78juiZmddv3eEyoz1gqRwP89OHreiX6fnXkfbce", + }, }, { - name: "invalid pattern", - input: fmt.Sprintf("bitfinex credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + bitfinexKey := "HxfuG198amaeCcYkASkto5VuIO-oXcplDV6JZ7OIEQZ" + bitfinexSecret := "kASkto5VuIO%c^HxfuG198amaeCcYkASkto5VuIO" + http.DefaultClient = client + c := rest.NewClientWithURL(*api).Credentials(key, secret) + } + `, + want: nil, }, } @@ -54,22 +67,15 @@ func TestBitFinex_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -81,6 +87,7 @@ func TestBitFinex_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bitlyaccesstoken/bitlyaccesstoken_test.go b/pkg/detectors/bitlyaccesstoken/bitlyaccesstoken_test.go index cdd0e6bb8..a79913f78 100644 --- a/pkg/detectors/bitlyaccesstoken/bitlyaccesstoken_test.go +++ b/pkg/detectors/bitlyaccesstoken/bitlyaccesstoken_test.go @@ -2,47 +2,15 @@ package bitlyaccesstoken import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "2xN7puShxzNf5fZleQthTg305lKr7KrbW95D3gSD" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - bitlyToken := "2xN7puShxzNf5fZleQthTg305lKr7KrbW95D3gSD" - req.Header.Set("Authorization", "Bearer " + bitlyToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "2xN7puShxzNf5fZleQthTg305l95D3gSD%c^" -) - func TestBitlyAccessToken_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBitlyAccessToken_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bitly credentials: %s", validPattern), - want: []string{"2xN7puShxzNf5fZleQthTg305lKr7KrbW95D3gSD"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bitlyToken := "2xN7puShxzNf5fZleQthTg305lKr7KrbW95D3gSD" + req.Header.Set("Authorization", "Bearer " + bitlyToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"2xN7puShxzNf5fZleQthTg305lKr7KrbW95D3gSD"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"2xN7puShxzNf5fZleQthTg305lKr7KrbW95D3gSD"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bitly} + {bitly AQAAABAAA TKymDGZ62qKyWXsq00Nyp-w1bTJn7bFlXWTaH-2i} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"TKymDGZ62qKyWXsq00Nyp-w1bTJn7bFlXWTaH-2i"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bitly credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bitlyToken := "2xN7puShxzNf5fZleQthTg305l95D3gSD%c^" + req.Header.Set("Authorization", "Bearer " + bitlyToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBitlyAccessToken_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBitlyAccessToken_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bitmex/bitmex_test.go b/pkg/detectors/bitmex/bitmex_test.go index 123020939..209e1afd2 100644 --- a/pkg/detectors/bitmex/bitmex_test.go +++ b/pkg/detectors/bitmex/bitmex_test.go @@ -5,50 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "bitmexkey: I4_XpH-fJJiLFn--Wo7rnlXE + bitmexsecret: W_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY " - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - bitmexKey := " I4_XpH-fJJiLFn--Wo7rnlXE " - bitmexSecret := " W_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY " - - signature, err := generateSecretSignature(bitmexKey, bitmexSecret) - if err != nil{ - return err - } - - req.Header.Set("api-signature", signature) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "bitmexkey: mELzXm4bSlWv49JLc%c^ bitmexsecret: IXpH-fJJiLFn--Wo7rnlXE" -) - func TestBitmex_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -59,19 +21,80 @@ func TestBitmex_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"I4_XpH-fJJiLFn--Wo7rnlXEW_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bitmexKey := " EPwUIxOIveS463D_2O9LFgkz " + bitmexSecret := " W_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY " + + signature, err := generateSecretSignature(bitmexKey, bitmexSecret) + if err != nil{ + return err + } + + req.Header.Set("api-signature", signature) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"EPwUIxOIveS463D_2O9LFgkzW_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"I4_XpH-fJJiLFn--Wo7rnlXEW_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bitmex EPwUIxOIveS463D_2O9LFgkz } + {bitmex AQAAABAAA W_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY } + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"EPwUIxOIveS463D_2O9LFgkzW_HlMtrmELzXm4bSlWv49JLcgvg5hvu467WbbnpmoEA-RjrY"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bitmexKey := "mELzXm4bSlWv49JLc%c^" + bitmexSecret := "IXpH-fJJiLFn--Wo7rnlXE" + + signature, err := generateSecretSignature(bitmexKey, bitmexSecret) + if err != nil{ + return err + } + + req.Header.Set("api-signature", signature) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -79,22 +102,15 @@ func TestBitmex_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -106,6 +122,7 @@ func TestBitmex_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/blazemeter/blazemeter_test.go b/pkg/detectors/blazemeter/blazemeter_test.go index a7ccff213..2f5d6f45d 100644 --- a/pkg/detectors/blazemeter/blazemeter_test.go +++ b/pkg/detectors/blazemeter/blazemeter_test.go @@ -2,62 +2,15 @@ package blazemeter import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "sjbuxa3m-vs4n-ykl8-8jpv-i09hdidciolp" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - blazemeterToken := "sjbuxa3m-vs4n-ykl8-8jpv-i09hdidciolp" - req.Header.Set("Authorization", "Bearer " + blazemeterToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else if resp.StatusCode == http.UnAuthorized { - // if auth failed try runscope token - runScope := "q2n4fn1k-wly8-11pm-tfw6-hnltkxgemtpk" - req.Header.Set("Authorization", "Bearer " + runScope) - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "sjbuxa3m-vs4n- ykl8-8jpv#i09hdidciolp" -) - func TestBlazeMeter_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -68,19 +21,66 @@ func TestBlazeMeter_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("blazemeter credentials: %s", validPattern), - want: []string{"sjbuxa3m-vs4n-ykl8-8jpv-i09hdidciolp"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + blazemeterToken := "sjbuxa3m-vs4n-ykl8-8jpv-i09hdidciolp" + req.Header.Set("Authorization", "Bearer " + blazemeterToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"sjbuxa3m-vs4n-ykl8-8jpv-i09hdidciolp"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"q2n4fn1k-wly8-11pm-tfw6-hnltkxgemtpk", "sjbuxa3m-vs4n-ykl8-8jpv-i09hdidciolp"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {runscope} + {runscope AQAAABAAA vzn9dy84-mnvd-alqd-4pbf-cn618kvo26le} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"vzn9dy84-mnvd-alqd-4pbf-cn618kvo26le"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("blazemeter credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + blazemeterToken := "sjbuxa3m-vs4n- ykl8-8jpv#i09hdidciolp" + req.Header.Set("Authorization", "Bearer " + blazemeterToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -88,22 +88,15 @@ func TestBlazeMeter_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -115,6 +108,7 @@ func TestBlazeMeter_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/blitapp/blitapp_test.go b/pkg/detectors/blitapp/blitapp_test.go index 2728777cd..a759f7949 100644 --- a/pkg/detectors/blitapp/blitapp_test.go +++ b/pkg/detectors/blitapp/blitapp_test.go @@ -2,47 +2,15 @@ package blitapp import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "I_MncTA8nlFcqlBCakI5vwkwFD4_zRUYZKt8hyd" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - blitAppKey := "I_MncTA8nlFcqlBCakI5vwkwFD4_zRUYZKt8hyd" - req.Header.Set("API-Key", blitAppKey) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "%blitAppKey:I_Mn%^&*qlBCakI5vwkwFD4_zRUY" -) - func TestBlitApp_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBlitApp_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("blitapp credentials: %s", validPattern), - want: []string{"I_MncTA8nlFcqlBCakI5vwkwFD4_zRUYZKt8hyd"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + blitAppKey := "I_MncTA8nlFcqlBCakI5vwkwFD4_zRUYZKt8hyd" + req.Header.Set("API-Key", blitAppKey) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"I_MncTA8nlFcqlBCakI5vwkwFD4_zRUYZKt8hyd"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"I_MncTA8nlFcqlBCakI5vwkwFD4_zRUYZKt8hyd"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {blitapp} + {blitapp AQAAABAAA 188hN_78_V86WbCBVJd6OLMQJTHva7cbSf8HDFo} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"188hN_78_V86WbCBVJd6OLMQJTHva7cbSf8HDFo"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + blitAppKey := "I_Mn%^&*qlBCakI5vwkwFD4_zRUY" + req.Header.Set("API-Key", blitAppKey) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBlitApp_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBlitApp_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/blocknative/blocknative_test.go b/pkg/detectors/blocknative/blocknative_test.go index bdb560f82..406bacafc 100644 --- a/pkg/detectors/blocknative/blocknative_test.go +++ b/pkg/detectors/blocknative/blocknative_test.go @@ -2,47 +2,15 @@ package blocknative import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "76e50995-059f-3d1a-af8e-cc85fc05eb03" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - blocknativeSecret := "76e50995-059f-3d1a-af8e-cc85fc05eb03" - req.Header.Set("Authorization", blocknativeSecret) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "2xN7puShxzNf5fZleQthTg305l95D3gSD%c^" -) - func TestBlockNative_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBlockNative_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("blocknative credentials: %s", validPattern), - want: []string{"76e50995-059f-3d1a-af8e-cc85fc05eb03"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + blocknativeSecret := "76e50995-059f-3d1a-af8e-cc85fc05eb03" + req.Header.Set("Authorization", blocknativeSecret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"76e50995-059f-3d1a-af8e-cc85fc05eb03"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"76e50995-059f-3d1a-af8e-cc85fc05eb03"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {blocknative} + {blocknative AQAAABAAA 7b15f7f8-52a8-849d-384e-20b4c0de82dd} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"7b15f7f8-52a8-849d-384e-20b4c0de82dd"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("blocknative credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + blocknativeSecret := "2xN7puShxzNf5fZleQthTg305l95D3gSD%c^" + req.Header.Set("Authorization", blocknativeSecret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBlockNative_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBlockNative_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/blogger/blogger_test.go b/pkg/detectors/blogger/blogger_test.go index 13bc28111..c7586c90f 100644 --- a/pkg/detectors/blogger/blogger_test.go +++ b/pkg/detectors/blogger/blogger_test.go @@ -2,44 +2,15 @@ package blogger import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "fnWLw7pz1tc6uCzq6qocQZIxRF6SqUaOOkLqePY" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/blogger/blogs?key=fnWLw7pz1tc6uCzq6qocQZIxRF6SqUaOOkLqePY" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "fnWL(w7pz1t)6uCz-q6qocQZIxRF6S/UqePY" -) - func TestBlogger_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -50,19 +21,70 @@ func TestBlogger_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("blogger credentials: %s", validPattern), - want: []string{"fnWLw7pz1tc6uCzq6qocQZIxRF6SqUaOOkLqePY"}, + name: "valid pattern", + input: ` + func main() { + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", "https://api.example.com/v1/blogger/blogs?key=fnWLw7pz1tc6uCzq6qocQZIxRF6SqUaOOkLqePY", http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + + // Check response status + if resp.StatusCode == http.StatusOK { + fmt.Println("Request successful!") + } else { + fmt.Println("Request failed with status:", resp.Status) + } + } + `, + want: []string{"fnWLw7pz1tc6uCzq6qocQZIxRF6SqUaOOkLqePY"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"fnWLw7pz1tc6uCzq6qocQZIxRF6SqUaOOkLqePY"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {blogger} + {blogger AQAAABAAA mtkwpygpNROxOgLZCnEvl7gNme1IuFiQm9oxPzJ} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"mtkwpygpNROxOgLZCnEvl7gNme1IuFiQm9oxPzJ"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("blogger credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", "https://api.example.com/v1/blogger/blogs?key=fnWL(w7pz1t)6uCz-q6qocQZIxRF6S/UqePY", http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + + // Check response status + if resp.StatusCode == http.StatusOK { + fmt.Println("Request successful!") + } else { + fmt.Println("Request failed with status:", resp.Status) + } + } + `, + want: nil, }, } @@ -70,22 +92,15 @@ func TestBlogger_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -97,6 +112,7 @@ func TestBlogger_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bombbomb/bombbomb_test.go b/pkg/detectors/bombbomb/bombbomb_test.go index 7bf8db43c..00af1e06a 100644 --- a/pkg/detectors/bombbomb/bombbomb_test.go +++ b/pkg/detectors/bombbomb/bombbomb_test.go @@ -2,23 +2,15 @@ package bombbomb import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = ` - bombbombToken := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" - req.Header.Set("Authorization", bombbombToken) - ` - invalidPattern = "eyJhbGciOiJIUzI1N^iIsInRkpXVCJ9.ey$JzdWIiOiIxMjM0NTY3ODkwIiwibmFtZwiaWF0IjoxNTE2MjM5MDIyfQ.S&flKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" -) - func TestBombBomb_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -29,14 +21,34 @@ func TestBombBomb_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bombbomb credentials: %s", validPattern), - want: []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"}, + name: "valid pattern", + input: ` + bombbombToken := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" + req.Header.Set("Authorization", bombbombToken) + `, + want: []string{"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bombbomb credentials: %s", invalidPattern), - want: nil, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bombbomb} + {bombbomb AQAAABAAA eyJioGciOiJIU9I1NiIsInR5cCI6IkpXVCJ9.eyJJdWIiOiIxMjM0NTY3ODkwIiwibmFtZSJ6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5d} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"eyJioGciOiJIU9I1NiIsInR5cCI6IkpXVCJ9.eyJJdWIiOiIxMjM0NTY3ODkwIiwibmFtZSJ6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5d"}, + }, + { + name: "invalid pattern", + input: ` + bombbombToken := "eyJhbGciOiJIUzI1N^iIsInRkpXVCJ9.ey$JzdWIiOiIxMjM0NTY3ODkwIiwibmFtZwiaWF0IjoxNTE2MjM5MDIyfQ.S&flKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" + req.Header.Set("Authorization", bombbombToken) + `, + want: nil, }, } @@ -44,22 +56,15 @@ func TestBombBomb_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -71,6 +76,7 @@ func TestBombBomb_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/boostnote/boostnote_test.go b/pkg/detectors/boostnote/boostnote_test.go index a64132615..871e2cabf 100644 --- a/pkg/detectors/boostnote/boostnote_test.go +++ b/pkg/detectors/boostnote/boostnote_test.go @@ -2,47 +2,15 @@ package boostnote import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "fb1026ac5994e3ad01799fe040289317ba2594a20e9e45307a143be82b49d213" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - boostnoteKey := "fb1026ac5994e3ad01799fe040289317ba2594a20e9e45307a143be82b49d213" - req.Header.Set("Authorization", "Bearer " + boostnoteKey) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "#^fb1026ac59=4e3ad01799fe04028931___4a20e9e45307a143be82b49d213$" -) - func TestBoostNote_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBoostNote_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("boostnote credentials: %s", validPattern), - want: []string{"fb1026ac5994e3ad01799fe040289317ba2594a20e9e45307a143be82b49d213"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + boostnoteKey := "fb1026ac5994e3ad01799fe040289317ba2594a20e9e45307a143be82b49d213" + req.Header.Set("Authorization", "Bearer " + boostnoteKey) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"fb1026ac5994e3ad01799fe040289317ba2594a20e9e45307a143be82b49d213"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"fb1026ac5994e3ad01799fe040289317ba2594a20e9e45307a143be82b49d213"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {boostnote} + {boostnote AQAAABAAA a546e80a8018e1c5e37e4a3366a20aa363489691d2ca335e3a082550d8a92120} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"a546e80a8018e1c5e37e4a3366a20aa363489691d2ca335e3a082550d8a92120"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("boostnote credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + boostnoteKey := "#^fb1026ac59=4e3ad01799fe04028931___4a20e9e45307a143be82b49d213$" + req.Header.Set("Authorization", "Bearer " + boostnoteKey) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBoostNote_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBoostNote_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/borgbase/borgbase_test.go b/pkg/detectors/borgbase/borgbase_test.go index fdd7b6597..603979627 100644 --- a/pkg/detectors/borgbase/borgbase_test.go +++ b/pkg/detectors/borgbase/borgbase_test.go @@ -2,48 +2,15 @@ package borgbase import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "FoHclCFSi_aV09jowJQ4RUF_MiqW6ioqq6_OcyB0PFlV-mQ1yoFjk5JLlxbzRUzKTA6vsfR8wq6TNc83rtNKlkD092Sj1c9CbPVBXlHksy.sT2I/so6bMGdPcqxzbjrxYgAUiORgqJDeTet4gKOQlZpt" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - payload := '{"query":"{ sshList {id, name}}"}' - req, err := http.NewRequest("POST", url, payload) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - borgbaseToken := "FoHclCFSi_aV09jowJQ4RUF_MiqW6ioqq6_OcyB0PFlV-mQ1yoFjk5JLlxbzRUzKTA6vsfR8wq6TNc83rtNKlkD092Sj1c9CbPVBXlHksy.sT2I/so6bMGdPcqxzbjrxYgAUiORgqJDeTet4gKOQlZpt" - req.Header.Set("Authorization", "Bearer " + borgbaseToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "mQ1yoFjk5JLlxbzRUzKTA6vsfR8wq,6TNc83rtNKlkD092Sj1c9CbPVBXlHksy%c^so6bMGdPcqxzbjrxYgAUiORgqJDeTet4gKOQlZpt" -) - func TestBorgBase_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -54,19 +21,68 @@ func TestBorgBase_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("borgbase credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + payload := '{"query":"{ sshList {id, name}}"}' + req, err := http.NewRequest("POST", url, payload) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + borgbaseToken := "FoHclCFSi_aV09jowJQ4RUF_MiqW6ioqq6_OcyB0PFlV-mQ1yoFjk5JLlxbzRUzKTA6vsfR8wq6TNc83rtNKlkD092Sj1c9CbPVBXlHksy.sT2I/so6bMGdPcqxzbjrxYgAUiORgqJDeTet4gKOQlZpt" + req.Header.Set("Authorization", "Bearer " + borgbaseToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"FoHclCFSi_aV09jowJQ4RUF_MiqW6ioqq6_OcyB0PFlV-mQ1yoFjk5JLlxbzRUzKTA6vsfR8wq6TNc83rtNKlkD092Sj1c9CbPVBXlHksy.sT2I/so6bMGdPcqxzbjrxYgAUiORgqJDeTet4gKOQlZpt"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {borgbase} + {borgbase AQAAABAAA KtSE0ggsVsvvDQPHau2ItXW8yi7YsFTho4wHTTjCDShrWgYA421GzfXMwkOYklS6psQd1W8459NvmcZSmr7_LKqQffBGYAVvexM1D4JxRcQS49H3rnFlwDYspB5_m7AxvmbPrpWj8TfNm7zKCa2Ed} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"KtSE0ggsVsvvDQPHau2ItXW8yi7YsFTho4wHTTjCDShrWgYA421GzfXMwkOYklS6psQd1W8459NvmcZSmr7_LKqQffBGYAVvexM1D4JxRcQS49H3rnFlwDYspB5_m7AxvmbPrpWj8TfNm7zKCa2Ed"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("borgbase credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + payload := '{"query":"{ sshList {id, name}}"}' + req, err := http.NewRequest("POST", url, payload) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + borgbaseToken := "mQ1yoFjk5JLlxbzRUzKTA6vsfR8wq,6TNc83rtNKlkD092Sj1c9CbPVBXlHksy%c^so6bMGdPcqxzbjrxYgAUiORgqJDeTet4gKOQlZpt" + req.Header.Set("Authorization", "Bearer " + borgbaseToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -74,22 +90,15 @@ func TestBorgBase_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -101,6 +110,7 @@ func TestBorgBase_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/box/box_test.go b/pkg/detectors/box/box_test.go index 49b3199b6..d4e23d42f 100644 --- a/pkg/detectors/box/box_test.go +++ b/pkg/detectors/box/box_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" @@ -19,9 +20,43 @@ func TestBox_Pattern(t *testing.T) { want []string }{ { - name: "typical pattern", - input: "box_access_token = 'Ogowv5cj5AJJjO5F3daNHbKJDdPud0CZ'", - want: []string{"Ogowv5cj5AJJjO5F3daNHbKJDdPud0CZ"}, + name: "valid pattern", + input: ` + [INFO] request received to fetch box data + [INFO] sending API request to box API + [DEBUG] using Key=Ogowv5cj5AJJjO5F3daNHbKJDdPud0CZ + [DEBUG] request sent successfully + [INFO] response received: 200 OK + [DEBUG] fetch data from the database for ID Qje1HjJmgrNzOQpQZROEeYjmHbD2qdFF + [INFO] data returned + `, + want: []string{"Ogowv5cj5AJJjO5F3daNHbKJDdPud0CZ"}, + }, + { + name: "valid pattern - xml", + input: ` + + GLOBAL + {box} + {box AQAAABAAA Dxb2zNdFF2QTSMwrZJnoeD54Dc4zZAIW} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"Dxb2zNdFF2QTSMwrZJnoeD54Dc4zZAIW"}, + }, + { + name: "invalid pattern", + input: ` + [INFO] request received to fetch box data + [INFO] sending API request to box API + [DEBUG] using Key=Ogow-v5cj-5AJJ-jO5F-3daN-HbKJ-DdPu-d0CZ + [DEBUG] request sent successfully + [ERROR] response received: 401 UnAuthorized + [INFO] nothing to return + `, + want: nil, }, } @@ -29,22 +64,15 @@ func TestBox_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -56,6 +84,7 @@ func TestBox_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/boxoauth/boxoauth_test.go b/pkg/detectors/boxoauth/boxoauth_test.go index bf7160a35..473c609e3 100644 --- a/pkg/detectors/boxoauth/boxoauth_test.go +++ b/pkg/detectors/boxoauth/boxoauth_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" @@ -48,22 +49,15 @@ func TestBoxOauth_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -75,6 +69,7 @@ func TestBoxOauth_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/braintreepayments/braintreepayments_test.go b/pkg/detectors/braintreepayments/braintreepayments_test.go index b66611ae4..6c5ea244d 100644 --- a/pkg/detectors/braintreepayments/braintreepayments_test.go +++ b/pkg/detectors/braintreepayments/braintreepayments_test.go @@ -5,44 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "braintreeKey: f7b3cb83a7fdb915a71ce17ab8a903cc \n braintreeId: kmajpm4h1pqoqxyo" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - braintreeKey := "f7b3cb83a7fdb915a71ce17ab8a903cc" - braintreeId := "kmajpm4h1pqoqxyo" - req.SetBasicAuth(braintreeKey, braintreeId) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "braintreeCreds: f7b3cb83a7fdb915a71ce17ab8a903cckmajpm4h1pqoqxyo" -) - func TestBrainTreePayments_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,68 @@ func TestBrainTreePayments_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"f7b3cb83a7fdb915a71ce17ab8a903cc"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + braintreeKey := "f7b3cb83a7fdb915a71ce17ab8a903cc" + braintreeId := "kmajpm4h1pqoqxyo" + req.SetBasicAuth(braintreeKey, braintreeId) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"f7b3cb83a7fdb915a71ce17ab8a903cc"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"f7b3cb83a7fdb915a71ce17ab8a903cc"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {braintree jvbs4thxyzhh8n00} + {braintree AQAAABAAA 7d1ab9c76bea2cfb80a29fef8f1e0b12} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"7d1ab9c76bea2cfb80a29fef8f1e0b12"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + braintreeKey := "f7b3cb83a7fdb915a71ce17ab8a903cckmajpm4h1pqoqxyo" + braintreeId := "kmajpm4h1pqoqxyo" + req.SetBasicAuth(braintreeKey, braintreeId) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +90,15 @@ func TestBrainTreePayments_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +110,7 @@ func TestBrainTreePayments_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/brandfetch/brandfetch_test.go b/pkg/detectors/brandfetch/brandfetch_test.go index 0085ffca2..b06e6ea82 100644 --- a/pkg/detectors/brandfetch/brandfetch_test.go +++ b/pkg/detectors/brandfetch/brandfetch_test.go @@ -2,47 +2,15 @@ package brandfetch import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "uHOAdwfQ7sD2yOpur72UqyUeIqnFwILOIlEPyBtJ" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - brandfetchAPIKey := "uHOAdwfQ7sD2yOpur72UqyUeIqnFwILOIlEPyBtJ" - req.Header.Set("x-api-key", brandfetchAPIKey) // brandfetch secret - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "yUeIqnFwILOIlEPyBt+=JOAdwfQ7sD2uHOAdwf2U[qy]UeIqnFwILOIlEPyBtJ^" -) - func TestBrandFetch_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBrandFetch_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("brandfetch credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + brandfetchAPIKey := "uHOAdwfQ7sD2yOpur72UqyUeIqnFwILOIlEPyBtJ" + req.Header.Set("x-api-key", brandfetchAPIKey) // brandfetch secret + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"uHOAdwfQ7sD2yOpur72UqyUeIqnFwILOIlEPyBtJ"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {uSiXZ-NMpDW-ZJQFSN-5wkT7SqQ8-mDbr9K2pl} + {brandfetch AQAAABAAA uSiXZNMpDWWhZJQFSNkE5wkT7SqQ8B3mDbr9K2pl} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"uSiXZNMpDWWhZJQFSNkE5wkT7SqQ8B3mDbr9K2pl"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("brandfetch credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + brandfetchAPIKey := "yUeIqnFwILOIlEPyBt+=JOAdwfQ7sD2uHOAdwf2U[qy]UeIqnFwILOIlEPyBtJ^" + req.Header.Set("x-api-key", brandfetchAPIKey) // brandfetch secret + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBrandFetch_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBrandFetch_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/browserstack/browserstack_test.go b/pkg/detectors/browserstack/browserstack_test.go index 4e9f08668..97478c750 100644 --- a/pkg/detectors/browserstack/browserstack_test.go +++ b/pkg/detectors/browserstack/browserstack_test.go @@ -2,52 +2,15 @@ package browserstack import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "accessKey: RxLVnOlvj3V4bh4RBwOd / username: Dun88d_-_-.4yggxTlrq" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - if browserstackKey, _ := os.GetEnv("ACCESS_KEY"); browserstackKey != "RxLVnOlvj3V4bh4RBwOd" { - return fmt.Errorf("invalid accessKey: %v expected: %v", "RxLVnOlvj3V4bh4RBwOd", "1YZazUAPFOiaIFljWDhC") - } - - if browserstackUser, _ := os.GetEnv("USER_NAME"); browserstackUser != "Dun88d_-_-.4yggxTlrq" { - return fmt.Errorf("invalid userName: %v", "Dun88d_-_-.4yggxTlrq") - } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "BS_USERNAME: Dun--d_$_$.4yggxTlrq%c^ \n BS_AUTHKEY: Dun88d_)" -) - func TestBrowserStack_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -58,19 +21,81 @@ func TestBrowserStack_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("browserstack credentials: %s", validPattern), - want: []string{"RxLVnOlvj3V4bh4RBwOdDun88d_-_-.4yggxTlrq"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + if browserstackKey, _ := os.GetEnv("ACCESS_KEY"); browserstackKey != "cK1bq7JREJtMf1meaGgs" { + return fmt.Errorf("invalid accessKey: %v expected: %v", browserstackKey, "1YZazUAPFOiaIFljWDhC") + } + + if browserstackUser, _ := os.GetEnv("USER_NAME"); browserstackUser != "truffle-security91" { + return fmt.Errorf("invalid userName: %v", "truffle-security91") + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{ + "cK1bq7JREJtMf1meaGgstruffle-security91", + "1YZazUAPFOiaIFljWDhCbrowserstackUser", + "1YZazUAPFOiaIFljWDhCtruffle-security91", + "cK1bq7JREJtMf1meaGgsbrowserstackUser", + }, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"RxLVnOlvj3V4bh4RBwOdDun88d_-_-.4yggxTlrq", "RxLVnOlvj3V4bh4RBwOdbrowserstackUser", "RxLVnOlvj3V4bh4RBwOdDun88d_-_-.4yggxTlrq", "RxLVnOlvj3V4bh4RBwOdDun88d_-_-.4yggxTlrq"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {BS_USERNAME Q8fo0ADq_-_Cj4HtE4Gr} + {BROWSERSTACK_ACCESS_KEY AQAAABAAA 25IQfQKfEm26vKV96nao} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"25IQfQKfEm26vKV96naoQ8fo0ADq_-_Cj4HtE4Gr"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("browserstack credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + if browserstackKey, _ := os.GetEnv("ACCESS_KEY"); browserstackKey != "RxLVnOlvj3#V4bh4RBwOd" { + return fmt.Errorf("invalid accessKey: %v expected: %v", browserstackKey, "RxLVnOlvj3#V4bh4RBwOd") + } + + if browserstackUser, _ := os.GetEnv("USER_NAME"); browserstackUser != "test" { + return fmt.Errorf("invalid userName: %v", browserstackUser) + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -78,22 +103,15 @@ func TestBrowserStack_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -105,6 +123,7 @@ func TestBrowserStack_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/browshot/browshot_test.go b/pkg/detectors/browshot/browshot_test.go index 19656366b..16ba249ba 100644 --- a/pkg/detectors/browshot/browshot_test.go +++ b/pkg/detectors/browshot/browshot_test.go @@ -2,44 +2,15 @@ package browshot import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "AemQ06R35S1Y8rXnOzYvT8I4-a7u" - complexPattern = ` - func main() { - url := "https://api.browshot.com/v1/instances/list?key=AemQ06R35S1Y8rXnOzYvT8I4-a7u" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "2xN7puShxzNf5fZleQt#hTg305l95D3gSD-c^" -) - func TestBrowShot_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -50,19 +21,67 @@ func TestBrowShot_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("browshot credentials: %s", validPattern), - want: []string{"AemQ06R35S1Y8rXnOzYvT8I4-a7u"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.browshot.com/v1/instances/list?key=AemQ06R35S1Y8rXnOzYvT8I4-a7u" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + + // Check response status + if resp.StatusCode == http.StatusOK { + fmt.Println("Request successful!") + } else { + fmt.Println("Request failed with status:", resp.Status) + } + } + `, + want: []string{"AemQ06R35S1Y8rXnOzYvT8I4-a7u"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"AemQ06R35S1Y8rXnOzYvT8I4-a7u"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {browshot} + {browshot AQAAABAAA SyGuw6JXLULnOEDZjiicnTtQ4FA3} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"SyGuw6JXLULnOEDZjiicnTtQ4FA3"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("browshot credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.browshot.com/v1/instances/list?key=2xN7puShxzNf5fZleQt#hTg305l95D3gSD-c^" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -70,22 +89,15 @@ func TestBrowShot_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -97,6 +109,7 @@ func TestBrowShot_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bscscan/bscscan_test.go b/pkg/detectors/bscscan/bscscan_test.go index 739f6ce7e..e5649eab9 100644 --- a/pkg/detectors/bscscan/bscscan_test.go +++ b/pkg/detectors/bscscan/bscscan_test.go @@ -2,44 +2,15 @@ package bscscan import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "HYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1" - complexPattern = ` - func main() { - url := "https://api.bscscan.com/v1/resource?apikey=HYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "2xHYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1thTg303gSD%c^" -) - func TestBscScan_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -50,19 +21,60 @@ func TestBscScan_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bscscan credentials: %s", validPattern), - want: []string{"HYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.bscscan.com/v1/resource?apikey=HYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"HYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"HYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bscscan} + {bscscan AQAAABAAA SLQOD6LO36MN446N44L98FDJR1AS5PYPTR} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"SLQOD6LO36MN446N44L98FDJR1AS5PYPTR"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bscscan credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.bscscan.com/v1/resource?apikey=2xHYZHPP4PBYXCOZAVK4FH55W4MRHYLALPU1thTg303gSD%c^" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -70,22 +82,15 @@ func TestBscScan_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -97,6 +102,7 @@ func TestBscScan_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/buddyns/buddyns_test.go b/pkg/detectors/buddyns/buddyns_test.go index 4cf65107f..078d9f7d6 100644 --- a/pkg/detectors/buddyns/buddyns_test.go +++ b/pkg/detectors/buddyns/buddyns_test.go @@ -2,47 +2,15 @@ package buddyns import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "kkmvdiolccw4v0tue4lu7l7kmnnb4ao8z25ezink" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - buddynsToken := "kkmvdiolccw4v0tue4lu7l7kmnnb4ao8z25ezink" - req.Header.Set("Authorization", "Token " + buddynsToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "diolccw4v0tue4lu7l7kmnnb4ao8z25ezink305l95D3gSD%c^" -) - func TestBuddyNs_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBuddyNs_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("buddyns credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + buddynsToken := "kkmvdiolccw4v0tue4lu7l7kmnnb4ao8z25ezink" + req.Header.Set("Authorization", "Token " + buddynsToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"kkmvdiolccw4v0tue4lu7l7kmnnb4ao8z25ezink"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {buddyns} + {buddyns AQAAABAAA jqcayapqh1soy2zlfdbs1j4ytn0mpgmeffzsu2yt} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"jqcayapqh1soy2zlfdbs1j4ytn0mpgmeffzsu2yt"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("buddyns credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + buddynsToken := "diolccw4v0tue4lu7l7kmnnb4ao8z25ezink305l95D3gSD%c^" + req.Header.Set("Authorization", "Token " + buddynsToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBuddyNs_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBuddyNs_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/budibase/budibase_test.go b/pkg/detectors/budibase/budibase_test.go index 962e26856..e5aa858a8 100644 --- a/pkg/detectors/budibase/budibase_test.go +++ b/pkg/detectors/budibase/budibase_test.go @@ -2,46 +2,15 @@ package budibase import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "b256def166fcdf4a429a1e83175105d5-fd36f3da1e934bf533cd0e68dbb80ed6a42e1178bd4200428d83e876e7d05e40b21e3a68888f826d" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - req.Header.Set("x-budibase-api-key", "b256def166fcdf4a429a1e83175105d5-fd36f3da1e934bf533cd0e68dbb80ed6a42e1178bd4200428d83e876e7d05e40b21e3a68888f826d") - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "diolccw4v0tue4lu7l7kmnnb4ao8z25ezink305l95D3gSD%c^" -) - func TestBudiBase_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -52,19 +21,64 @@ func TestBudiBase_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("budibase credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + req.Header.Set("x-budibase-api-key", "b256def166fcdf4a429a1e83175105d5-fd36f3da1e934bf533cd0e68dbb80ed6a42e1178bd4200428d83e876e7d05e40b21e3a68888f826d") + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"b256def166fcdf4a429a1e83175105d5-fd36f3da1e934bf533cd0e68dbb80ed6a42e1178bd4200428d83e876e7d05e40b21e3a68888f826d"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {budibase} + {budibase AQAAABAAA eb72aa19dafbd0166e16299e0bea6a35-96ab88e1b2691be47aa15b343e8e2b5a3be0564b704db9f2812b6e4decde312038c2f3ba00102e} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"eb72aa19dafbd0166e16299e0bea6a35-96ab88e1b2691be47aa15b343e8e2b5a3be0564b704db9f2812b6e4decde312038c2f3ba00102e"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("budibase credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + req.Header.Set("x-budibase-api-key", "diolccw4v0tue4lu7l7kmnnb4ao8z25ezink305l95D3gSD%c^") + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -72,22 +86,15 @@ func TestBudiBase_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -99,6 +106,7 @@ func TestBudiBase_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bugherd/bugherd_test.go b/pkg/detectors/bugherd/bugherd_test.go index bdff434cf..c6088709a 100644 --- a/pkg/detectors/bugherd/bugherd_test.go +++ b/pkg/detectors/bugherd/bugherd_test.go @@ -2,47 +2,15 @@ package bugherd import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "fisy6bbu6il4x96bekx587" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - bugherdToken := "fisy6bbu6il4x96bekx587" - req.Header.Set("Authorization", "Basic " + buddynsToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "fisy6bbu+6il4x()96bekx587-7l7kmnnb4ao8z25ezink305l95D3gSD%c^" -) - func TestBugHerd_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBugHerd_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bugherd credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bugherdToken := "fisy6bbu6il4x96bekx587" + req.Header.Set("Authorization", "Basic " + buddynsToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"fisy6bbu6il4x96bekx587"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bugherd} + {bugherd AQAAABAAA mx2rxr8ztizo8kytvx1kan} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"mx2rxr8ztizo8kytvx1kan"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bugherd credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bugherdToken := "fisy6bbu+6il4x()96bekx587-7l7kmnnb4ao8z25ezink305l95D3gSD%c^" + req.Header.Set("Authorization", "Basic " + buddynsToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBugHerd_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBugHerd_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bugsnag/bugsnag_test.go b/pkg/detectors/bugsnag/bugsnag_test.go index a221b3b26..7b31971b2 100644 --- a/pkg/detectors/bugsnag/bugsnag_test.go +++ b/pkg/detectors/bugsnag/bugsnag_test.go @@ -2,47 +2,15 @@ package bugsnag import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "wz9450iu-iewm-jonx-eab8-0ibxwadddm8i" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - bugsnagToken := "wz9450iu-iewm-jonx-eab8-0ibxwadddm8i" - req.Header.Set("Authorization", "token " + bugsnagToken) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "bugsnagToken: %c^wz9450iu-iewm-jonx-eab8-" -) - func TestBugSnag_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBugSnag_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bugsnag credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bugsnagToken := "wz9450iu-iewm-jonx-eab8-0ibxwadddm8i" + req.Header.Set("Authorization", "token " + bugsnagToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"wz9450iu-iewm-jonx-eab8-0ibxwadddm8i"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bugsnag} + {bugsnag AQAAABAAA heatep16-k3fw-dflj-ucc1-ay1lu0in3p7k} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"heatep16-k3fw-dflj-ucc1-ay1lu0in3p7k"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("bugsnag credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bugsnagToken := "%c^wz9450iu-iewm-jonx-eab8-" + req.Header.Set("Authorization", "token " + bugsnagToken) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBugSnag_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBugSnag_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/buildkite/v1/buildkite_test.go b/pkg/detectors/buildkite/v1/buildkite_test.go index 5005b11e0..e4aa9d298 100644 --- a/pkg/detectors/buildkite/v1/buildkite_test.go +++ b/pkg/detectors/buildkite/v1/buildkite_test.go @@ -2,47 +2,15 @@ package buildkite import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "kimu4axq3jxxdj8un0kpo3ua2ucr05zmhh4de0r6" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - buildkite_secret := "kimu4axq3jxxdj8un0kpo3ua2ucr05zmhh4de0r6" - req.Header.Set("Authorization", "Bearer " + buildkite_secret) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "buildkite: %c^wz9450iu-buildkite_secret-jonx-eab8" -) - func TestBuildKite_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBuildKite_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("buildkite credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + buildkite_secret := "kimu4axq3jxxdj8un0kpo3ua2ucr05zmhh4de0r6" + req.Header.Set("Authorization", "Bearer " + buildkite_secret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"kimu4axq3jxxdj8un0kpo3ua2ucr05zmhh4de0r6"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {buildkite} + {buildkite AQAAABAAA ssoj8umx032r2f6sintvtw582bwvxymxgifu6gmk} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"ssoj8umx032r2f6sintvtw582bwvxymxgifu6gmk"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("buildkite credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + buildkite_secret := "%c^wz9450iu-buildkite_secret-jonx-eab8" + req.Header.Set("Authorization", "Bearer " + buildkite_secret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBuildKite_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBuildKite_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/buildkite/v2/buildkite_test.go b/pkg/detectors/buildkite/v2/buildkite_test.go index 44b9cc645..c7eeb19f6 100644 --- a/pkg/detectors/buildkite/v2/buildkite_test.go +++ b/pkg/detectors/buildkite/v2/buildkite_test.go @@ -2,47 +2,15 @@ package buildkitev2 import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "bkua_hqlh73m51jtho0jh12wcf2758c8fcdbv05z023ly" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - buildkite_secret := "bkua_hqlh73m51jtho0jh12wcf2758c8fcdbv05z023ly" - req.Header.Set("Authorization", "Bearer " + buildkite_secret) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "bkua_: hqlh73m51jtho0jh12wcf2758c8fcdbv05z023ly-jonx-eab8" -) - func TestBuildKiteV2_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -53,19 +21,66 @@ func TestBuildKiteV2_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("buildkite credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + buildkite_secret := "bkua_hqlh73m51jtho0jh12wcf2758c8fcdbv05z023ly" + req.Header.Set("Authorization", "Bearer " + buildkite_secret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"bkua_hqlh73m51jtho0jh12wcf2758c8fcdbv05z023ly"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {} + {AQAAABAAA bkua_j8cqyoaodi7z1fzo8u5albtyw4x9gh83yx1m6ien} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"bkua_j8cqyoaodi7z1fzo8u5albtyw4x9gh83yx1m6ien"}, }, { - name: "invalid pattern", - input: fmt.Sprintf("buildkite credentials: %s", invalidPattern), - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + buildkite_secret := "bkua_hqlh73m51jtho0jh12wcf27v05z023ly-jonx-eab8" + req.Header.Set("Authorization", "Bearer " + buildkite_secret) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -73,22 +88,15 @@ func TestBuildKiteV2_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -100,6 +108,7 @@ func TestBuildKiteV2_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bulbul/bulbul_test.go b/pkg/detectors/bulbul/bulbul_test.go index c21734f6e..e9f4ced11 100644 --- a/pkg/detectors/bulbul/bulbul_test.go +++ b/pkg/detectors/bulbul/bulbul_test.go @@ -2,44 +2,15 @@ package bulbul import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "3kx19qpx748ldb75lsjicbs6ipit6ssm" - complexPattern = ` - func main() { - url := "https://api.bulbul.com/v1/users?key=3kx19qpx748ldb75lsjicbs6ipit6ssm" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "bulbulKey: %c^wz9450iu-3kx19qcbs6ipit6ssm-jonx-eab8" -) - func TestBulBul_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -50,19 +21,60 @@ func TestBulBul_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("bulbul credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.bulbul.com/v1/users?key=3kx19qpx748ldb75lsjicbs6ipit6ssm" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"3kx19qpx748ldb75lsjicbs6ipit6ssm"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bulbul} + {bulbul AQAAABAAA r9gk8o0ctd4xq4r66d3reahu9ku4i4ht} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"r9gk8o0ctd4xq4r66d3reahu9ku4i4ht"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.bulbul.com/v1/users?key=%c^wz9450iu-3kx19qcbs6ipit6ssm-jonx-eab8" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -70,22 +82,15 @@ func TestBulBul_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -97,6 +102,7 @@ func TestBulBul_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/bulksms/bulksms_test.go b/pkg/detectors/bulksms/bulksms_test.go index 9f1734af3..792b8cfcc 100644 --- a/pkg/detectors/bulksms/bulksms_test.go +++ b/pkg/detectors/bulksms/bulksms_test.go @@ -5,45 +5,12 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "bulksmsKey: (QGxPqRyzvt%xEKcV&#ePJGn)k0d9a \n bulksmsID: 381A26C47380B85F2DB572314-ACBDC267B-8" - complexPattern = ` - func main() { - url := "https://api.example.com/v1/resource" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - bulksmsKey := "(QGxPqRyzvt%xEKcV&#ePJGn)k0d9a" - bulksmsID := "381A26C47380B85F2DB572314-ACBDC267B-8" - - req.SetBasicAuth(bulksmsKey, bulksmsID) - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "bulksms creds: %c^wz9450iu-iewm-jonx-eab8-/F2DB572314-ACBDC267B-8" -) - func TestBulkSMS_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -54,19 +21,70 @@ func TestBulkSMS_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: validPattern, - want: []string{"QGxPqRyzvt%xEKcV&#ePJGn)k0d9a381A26C47380B85F2DB572314-ACBDC267B-8"}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bulksmsKey := "(QGxPqRyzvt%xEKcV&#ePJGn)k0d9a" + bulksmsID := "381A26C47380B85F2DB572314-ACBDC267B-8" + + req.SetBasicAuth(bulksmsKey, bulksmsID) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"QGxPqRyzvt%xEKcV&#ePJGn)k0d9a381A26C47380B85F2DB572314-ACBDC267B-8"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{"QGxPqRyzvt%xEKcV&#ePJGn)k0d9a381A26C47380B85F2DB572314-ACBDC267B-8"}, + name: "valid pattern - xml", + input: ` + + GLOBAL + {bulksms fXHnHK&cN8H!1r5ersTDIe6ZJ8j51} + {bulksms AQAAABAAA 04A1ED4D90D3E17-3968-66B6A571D--2134E} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"fXHnHK&cN8H!1r5ersTDIe6ZJ8j5104A1ED4D90D3E17-3968-66B6A571D--2134E"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.example.com/v1/resource" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + bulksmsKey := "(QGxPqRyzvt%xEKcV&#ePJGn)k0d9a" + bulksmsID := "%c^wz9450iu-iewm-jonx-eab8-/F2DB572314-ACBDC267B-8" + + req.SetBasicAuth(bulksmsKey, bulksmsID) + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -74,22 +92,15 @@ func TestBulkSMS_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -101,6 +112,7 @@ func TestBulkSMS_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{} diff --git a/pkg/detectors/buttercms/buttercms_test.go b/pkg/detectors/buttercms/buttercms_test.go index cf88df9ed..9fbd03692 100644 --- a/pkg/detectors/buttercms/buttercms_test.go +++ b/pkg/detectors/buttercms/buttercms_test.go @@ -2,44 +2,15 @@ package buttercms import ( "context" - "fmt" "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" ) -var ( - validPattern = "l7psk7wkedkpiyp4jrx5fjdnno8c89243of6yde8" - complexPattern = ` - func main() { - url := "https://api.buttercms.com/v2/posts?auth_token=l7psk7wkedkpiyp4jrx5fjdnno8c89243of6yde8" - - // Create a new request with the secret as a header - req, err := http.NewRequest("GET", url, http.NoBody) - if err != nil { - fmt.Println("Error creating request:", err) - return - } - - // Perform the request - client := &http.Client{} - resp, _ := client.Do(req) - defer resp.Body.Close() - - // Check response status - if resp.StatusCode == http.StatusOK { - fmt.Println("Request successful!") - } else { - fmt.Println("Request failed with status:", resp.Status) - } - } - ` - invalidPattern = "butterCMSToken: l7psk7wkedkpiyp4j(rx5fjdnn)" -) - func TestButterCMS_Pattern(t *testing.T) { d := Scanner{} ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) @@ -50,19 +21,60 @@ func TestButterCMS_Pattern(t *testing.T) { want []string }{ { - name: "valid pattern", - input: fmt.Sprintf("buttercms credentials: %s", validPattern), - want: []string{validPattern}, + name: "valid pattern", + input: ` + func main() { + url := "https://api.buttercms.com/v2/posts?auth_token=l7psk7wkedkpiyp4jrx5fjdnno8c89243of6yde8" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: []string{"l7psk7wkedkpiyp4jrx5fjdnno8c89243of6yde8"}, }, { - name: "valid pattern - complex", - input: complexPattern, - want: []string{validPattern}, + name: "valid pattern - xml", + input: ` + + GLOBAL + api-key + {buttercms AQAAABAAA xjndr06i2jiaoqs2plf8x0cgfz976blm1dctjqv9} + configuration for production + 2023-05-18T14:32:10Z + jenkins-admin + + `, + want: []string{"xjndr06i2jiaoqs2plf8x0cgfz976blm1dctjqv9"}, }, { - name: "invalid pattern", - input: invalidPattern, - want: nil, + name: "invalid pattern", + input: ` + func main() { + url := "https://api.buttercms.com/v2/posts?auth_token=l7psk7wkedkpiyp4j(rx5fjdnn)" + + // Create a new request with the secret as a header + req, err := http.NewRequest("GET", url, http.NoBody) + if err != nil { + fmt.Println("Error creating request:", err) + return + } + + // Perform the request + client := &http.Client{} + resp, _ := client.Do(req) + defer resp.Body.Close() + } + `, + want: nil, }, } @@ -70,22 +82,15 @@ func TestButterCMS_Pattern(t *testing.T) { t.Run(test.name, func(t *testing.T) { matchedDetectors := ahoCorasickCore.FindDetectorMatches([]byte(test.input)) if len(matchedDetectors) == 0 { - t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + t.Errorf("test %q failed: expected keywords %v to be found in the input", test.name, d.Keywords()) return } results, err := d.FromData(context.Background(), false, []byte(test.input)) - if err != nil { - t.Errorf("error = %v", err) - return - } + require.NoError(t, err) if len(results) != len(test.want) { - if len(results) == 0 { - t.Errorf("did not receive result") - } else { - t.Errorf("expected %d results, only received %d", len(test.want), len(results)) - } + t.Errorf("mismatch in result count: expected %d, got %d", len(test.want), len(results)) return } @@ -97,6 +102,7 @@ func TestButterCMS_Pattern(t *testing.T) { actual[string(r.Raw)] = struct{}{} } } + expected := make(map[string]struct{}, len(test.want)) for _, v := range test.want { expected[v] = struct{}{}