diff --git a/pkg/detectors/sentrytoken/sentrytoken.go b/pkg/detectors/sentrytoken/sentrytoken.go deleted file mode 100644 index 2ee37c582049..000000000000 --- a/pkg/detectors/sentrytoken/sentrytoken.go +++ /dev/null @@ -1,135 +0,0 @@ -package sentrytoken - -import ( - "context" - "encoding/json" - "errors" - "fmt" - regexp "github.com/wasilibs/go-re2" - "io" - "net/http" - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" - "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" -) - -type Scanner struct { - client *http.Client -} - -// Ensure the Scanner satisfies the interface at compile time. -var _ detectors.Detector = (*Scanner)(nil) - -var ( - defaultClient = common.SaneHttpClient() - - // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. - keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"sentry"}) + `\b([a-f0-9]{64})\b`) - - errUnauthorized = fmt.Errorf("token unauthorized") -) - -// 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{"sentry"} -} - -// FromData will find and optionally verify SentryToken secrets in a given set of bytes. -func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { - dataStr := string(data) - - matches := keyPat.FindAllStringSubmatch(dataStr, -1) - - for _, match := range matches { - if len(match) != 2 { - continue - } - resMatch := strings.TrimSpace(match[1]) - s1 := detectors.Result{ - DetectorType: detectorspb.DetectorType_SentryToken, - Raw: []byte(resMatch), - } - - if verify { - client := s.client - if client == nil { - client = defaultClient - } - isVerified, verificationErr := verifyToken(ctx, client, resMatch) - - switch { - case errors.Is(verificationErr, errUnauthorized): - s1.Verified = false - case isVerified: - s1.Verified = true - default: - s1.SetVerificationError(verificationErr, resMatch) - } - } - - results = append(results, s1) - } - - return results, nil -} - -type Response []Project - -type Project struct { - Organization Organization `json:"organization"` -} - -type Organization struct { - ID string `json:"id"` - Name string `json:"name"` -} - -func verifyToken(ctx context.Context, client *http.Client, token string) (bool, error) { - req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://sentry.io/api/0/projects/", nil) - if err != nil { - return false, err - } - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) - - res, err := client.Do(req) - if err != nil { - return false, err - } - defer res.Body.Close() - - var isVerified bool - switch res.StatusCode { - case http.StatusOK, http.StatusForbidden: - isVerified = true - case http.StatusUnauthorized: - return false, errUnauthorized - default: - return false, fmt.Errorf("unexpected HTTP response status %d", res.StatusCode) - } - - bytes, readErr := io.ReadAll(res.Body) - if readErr != nil { - return false, readErr - } - - var resp Response - if err = json.Unmarshal(bytes, &resp); err != nil { - return false, err - } - if len(resp) == 0 { - return false, fmt.Errorf("unexpected response body: %s", string(bytes)) - } - - return isVerified, err -} - -func (s Scanner) Type() detectorspb.DetectorType { - return detectorspb.DetectorType_SentryToken -} - -func (s Scanner) Description() string { - return "Sentry is an error tracking service that helps developers monitor and fix crashes in real time. Sentry tokens can be used to access and manage projects and organizations within Sentry." -} diff --git a/pkg/detectors/sentrytoken/v1/sentrytoken.go b/pkg/detectors/sentrytoken/v1/sentrytoken.go new file mode 100644 index 000000000000..c3b03e3a5805 --- /dev/null +++ b/pkg/detectors/sentrytoken/v1/sentrytoken.go @@ -0,0 +1,137 @@ +package sentrytoken + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + regexp "github.com/wasilibs/go-re2" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" + "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" +) + +type Scanner struct { + client *http.Client +} + +type Organization struct { + ID string `json:"id"` + Name string `json:"name"` +} + +// Ensure the Scanner satisfies the interface at compile time. +var _ detectors.Detector = (*Scanner)(nil) +var _ detectors.Versioner = (*Scanner)(nil) + +var ( + // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. + keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"sentry"}) + `\b([a-f0-9]{64})\b`) + + forbiddenError = "You do not have permission to perform this action." +) + +func (s Scanner) Version() int { + return 1 +} + +// 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{"sentry"} +} + +// FromData will find and optionally verify SentryToken secrets in a given set of bytes. +func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { + dataStr := string(data) + + // find all unique auth tokens + var uniqueAuthTokens = make(map[string]struct{}) + + for _, authToken := range keyPat.FindAllStringSubmatch(dataStr, -1) { + uniqueAuthTokens[authToken[1]] = struct{}{} + } + + for authToken := range uniqueAuthTokens { + s1 := detectors.Result{ + DetectorType: detectorspb.DetectorType_SentryToken, + Raw: []byte(authToken), + } + + if verify { + if s.client == nil { + s.client = common.SaneHttpClient() + } + extraData, isVerified, verificationErr := VerifyToken(ctx, s.client, authToken) + s1.Verified = isVerified + s1.SetVerificationError(verificationErr, authToken) + s1.ExtraData = extraData + } + + results = append(results, s1) + } + + return results, nil +} + +func VerifyToken(ctx context.Context, client *http.Client, token string) (map[string]string, bool, error) { + // api docs: https://docs.sentry.io/api/organizations/ + // this api will return 200 for user auth tokens with scope of org:<> + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://sentry.io/api/0/organizations/", nil) + if err != nil { + return nil, false, err + } + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + + resp, err := client.Do(req) + if err != nil { + return nil, false, err + } + defer func() { + _, _ = io.Copy(io.Discard, resp.Body) + _ = resp.Body.Close() + }() + + switch resp.StatusCode { + case http.StatusOK: + var organizations []Organization + if err = json.NewDecoder(resp.Body).Decode(&organizations); err != nil { + return nil, false, err + } + + var extraData = make(map[string]string) + for _, org := range organizations { + extraData[fmt.Sprintf("orginzation_%s", org.ID)] = org.Name + } + + return extraData, true, nil + case http.StatusForbidden: + var APIResp interface{} + if err = json.NewDecoder(resp.Body).Decode(&APIResp); err != nil { + return nil, false, err + } + + // if response contain the forbiddenError message it means the token is active but does not have the right scope for this API call + if strings.Contains(fmt.Sprintf("%v", APIResp), forbiddenError) { + return nil, true, nil + } + + return nil, false, nil + case http.StatusUnauthorized: + return nil, false, nil + default: + return nil, false, fmt.Errorf("unexpected HTTP response status %d", resp.StatusCode) + } +} + +func (s Scanner) Type() detectorspb.DetectorType { + return detectorspb.DetectorType_SentryToken +} + +func (s Scanner) Description() string { + return "Sentry is an error tracking service that helps developers monitor and fix crashes in real time. Sentry tokens can be used to access and manage projects and organizations within Sentry." +} diff --git a/pkg/detectors/sentrytoken/sentrytoken_integration_test.go b/pkg/detectors/sentrytoken/v1/sentrytoken_integration_test.go similarity index 76% rename from pkg/detectors/sentrytoken/sentrytoken_integration_test.go rename to pkg/detectors/sentrytoken/v1/sentrytoken_integration_test.go index 34729e95091e..58c2e02642f5 100644 --- a/pkg/detectors/sentrytoken/sentrytoken_integration_test.go +++ b/pkg/detectors/sentrytoken/v1/sentrytoken_integration_test.go @@ -52,6 +52,7 @@ func TestSentryToken_FromChunk(t *testing.T) { { DetectorType: detectorspb.DetectorType_SentryToken, Verified: true, + ExtraData: map[string]string{"orginzation_4508567357947904": "Truffle Security"}, }, }, wantErr: false, @@ -106,56 +107,6 @@ func TestSentryToken_FromChunk(t *testing.T) { wantErr: false, wantVerificationErr: true, }, - { - name: "found, good key but wrong scope", - s: Scanner{client: common.ConstantResponseHttpClient(403, responseBody403)}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a sentry super secret %s within", secret)), - verify: true, - }, - want: []detectors.Result{ - { - DetectorType: detectorspb.DetectorType_SentryToken, - Verified: true, - }, - }, - wantErr: false, - }, - { - name: "found, account deactivated", - s: Scanner{client: common.ConstantResponseHttpClient(200, responseAccountDeactivated)}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a sentry super secret %s within", secret)), - verify: true, - }, - want: []detectors.Result{ - { - DetectorType: detectorspb.DetectorType_SentryToken, - Verified: false, - }, - }, - wantErr: false, - wantVerificationErr: true, - }, - { - name: "found, account deactivated", - s: Scanner{client: common.ConstantResponseHttpClient(200, responseEmpty)}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a sentry super secret %s within", secret)), - verify: true, - }, - want: []detectors.Result{ - { - DetectorType: detectorspb.DetectorType_SentryToken, - Verified: false, - }, - }, - wantErr: false, - wantVerificationErr: true, - }, { name: "not found", s: Scanner{}, diff --git a/pkg/detectors/sentrytoken/sentrytoken_test.go b/pkg/detectors/sentrytoken/v1/sentrytoken_test.go similarity index 78% rename from pkg/detectors/sentrytoken/sentrytoken_test.go rename to pkg/detectors/sentrytoken/v1/sentrytoken_test.go index 8c7806ff43e0..d478b920045a 100644 --- a/pkg/detectors/sentrytoken/sentrytoken_test.go +++ b/pkg/detectors/sentrytoken/v1/sentrytoken_test.go @@ -12,9 +12,13 @@ import ( ) var ( - validPattern = "ad00eba0e2b5b057146e1b2b9373f86dbb0e712d106529111d97cb13f081de20" - invalidPattern = "ad00e?a0e2b5b057146e1b2b9373f86dbb0e712d106529111d97cb13f081de20" - keyword = "sentrytoken" + validPattern = ` + sentry_token := ad00eba0e2b5b057146e1b2b9373f86dbb0e712d106529111d97cb13f081de20 + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", sentry_token)) + ` + invalidPattern = "28ab769ecf2b465fake#0ea877d6494feffe5017a5824ec2920f24451423fake" + keyword = "sentry" + token = "ad00eba0e2b5b057146e1b2b9373f86dbb0e712d106529111d97cb13f081de20" ) func TestSentryToken_Pattern(t *testing.T) { @@ -27,18 +31,13 @@ func TestSentryToken_Pattern(t *testing.T) { }{ { name: "valid pattern - with keyword sentrytoken", - input: fmt.Sprintf("%s token = '%s'", keyword, validPattern), - want: []string{validPattern}, + input: validPattern, + want: []string{token}, }, { name: "valid pattern - ignore duplicate", input: fmt.Sprintf("%s token = '%s' | '%s'", keyword, validPattern, validPattern), - want: []string{validPattern}, - }, - { - name: "valid pattern - key out of prefix range", - input: fmt.Sprintf("%s keyword is not close to the real key in the data\n = '%s'", keyword, validPattern), - want: []string{}, + want: []string{token}, }, { name: "invalid pattern", diff --git a/pkg/detectors/sentrytoken/v2/sentrytoken.go b/pkg/detectors/sentrytoken/v2/sentrytoken.go new file mode 100644 index 000000000000..36c37bf8c824 --- /dev/null +++ b/pkg/detectors/sentrytoken/v2/sentrytoken.go @@ -0,0 +1,77 @@ +package sentrytoken + +import ( + "context" + "net/http" + + regexp "github.com/wasilibs/go-re2" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" + v1 "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sentrytoken/v1" + "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" +) + +type Scanner struct { + client *http.Client +} + +// Ensure the Scanner satisfies the interface at compile time. +var _ detectors.Detector = (*Scanner)(nil) +var _ detectors.Versioner = (*Scanner)(nil) + +var ( + // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. + keyPat = regexp.MustCompile(`\b(sntryu_[a-f0-9]{64})\b`) +) + +func (s Scanner) Version() int { + return 2 +} + +// 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{"sentry", "sntryu"} +} + +// FromData will find and optionally verify SentryToken secrets in a given set of bytes. +func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { + dataStr := string(data) + + // find all unique auth tokens + var uniqueAuthTokens = make(map[string]struct{}) + + for _, authToken := range keyPat.FindAllStringSubmatch(dataStr, -1) { + uniqueAuthTokens[authToken[1]] = struct{}{} + } + + for authToken := range uniqueAuthTokens { + s1 := detectors.Result{ + DetectorType: detectorspb.DetectorType_SentryToken, + Raw: []byte(authToken), + } + + if verify { + if s.client == nil { + s.client = common.SaneHttpClient() + } + extraData, isVerified, verificationErr := v1.VerifyToken(ctx, s.client, authToken) + s1.Verified = isVerified + s1.SetVerificationError(verificationErr, authToken) + s1.ExtraData = extraData + } + + results = append(results, s1) + } + + return results, nil +} + +func (s Scanner) Type() detectorspb.DetectorType { + return detectorspb.DetectorType_SentryToken +} + +func (s Scanner) Description() string { + return "Sentry is an error tracking service that helps developers monitor and fix crashes in real time. Sentry tokens can be used to access and manage projects and organizations within Sentry." +} diff --git a/pkg/detectors/sentrytoken/v2/sentrytoken_integration_test.go b/pkg/detectors/sentrytoken/v2/sentrytoken_integration_test.go new file mode 100644 index 000000000000..626a8bbdb722 --- /dev/null +++ b/pkg/detectors/sentrytoken/v2/sentrytoken_integration_test.go @@ -0,0 +1,180 @@ +//go:build detectors +// +build detectors + +package sentrytoken + +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 TestSentryToken_FromChunk(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors5") + if err != nil { + t.Fatalf("could not get test secrets from GCP: %s", err) + } + secret := testSecrets.MustGetField("SENTRYTOKEN_TOKEN") + inactiveSecret := testSecrets.MustGetField("SENTRYTOKEN_INACTIVE") + + type args struct { + ctx context.Context + data []byte + verify bool + } + tests := []struct { + name string + s Scanner + args args + want []detectors.Result + wantErr bool + wantVerificationErr bool + }{ + { + name: "found, verified", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a sentry secret %s within", secret)), + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_SentryToken, + Verified: true, + ExtraData: map[string]string{"orginzation_4508567357947904": "Truffle Security"}, + }, + }, + wantErr: false, + }, + { + name: "found, unverified", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a sentry 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_SentryToken, + Verified: false, + }, + }, + wantErr: false, + }, + { + name: "found, would be verified but for timeout", + s: Scanner{client: common.SaneHttpClientTimeOut(1 * time.Microsecond)}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a sentry super secret %s within", secret)), + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_SentryToken, + Verified: false, + }, + }, + wantErr: false, + wantVerificationErr: true, + }, + { + name: "found and valid but unexpected api response", + s: Scanner{client: common.ConstantResponseHttpClient(500, "")}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find a sentry super secret %s within", secret)), + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_SentryToken, + Verified: false, + }, + }, + wantErr: false, + wantVerificationErr: true, + }, + { + 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("Gitlab.FromData() error = %v, wantErr %v", err, tt.wantErr) + return + } + for i := range got { + if len(got[i].Raw) == 0 { + t.Fatal("no raw secret present") + } + if (got[i].VerificationError() != nil) != tt.wantVerificationErr { + t.Fatalf("wantVerificationError = %v, verification error = %v,", tt.wantVerificationErr, got[i].VerificationError()) + } + } + opts := cmpopts.IgnoreFields(detectors.Result{}, "Raw", "verificationError") + if diff := cmp.Diff(got, tt.want, opts); diff != "" { + t.Errorf("Gitlab.FromData() %s diff: (-got +want)\n%s", tt.name, diff) + } + }) + } +} + +const ( + responseBody403 = ` +[ + { + "organization": { + "id": "911964", + "slug": "wigslap", + "status": { + "id": "active", + "name": "active" + }, + "name": "wigslap" + } + } +] +` + responseAccountDeactivated = `{"detail": "Authentication credentials were not provided"}` + responseEmpty = `[]` +) + +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/sentrytoken/v2/sentrytoken_test.go b/pkg/detectors/sentrytoken/v2/sentrytoken_test.go new file mode 100644 index 000000000000..4cfdc0ac5c56 --- /dev/null +++ b/pkg/detectors/sentrytoken/v2/sentrytoken_test.go @@ -0,0 +1,90 @@ +package sentrytoken + +import ( + "context" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" + "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" +) + +var ( + validPattern = ` + sentry_token := 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 + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", sentry_token)) + ` + invalidPattern = "sntryu_822255ea24285a3f8f863dee3g1720fff21628cf331fbde22a16f27bef9cd7a6" + keyword = "sentry" + token = "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" +) + +func TestSentryToken_Pattern(t *testing.T) { + d := Scanner{} + ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) + tests := []struct { + name string + input string + want []string + }{ + { + name: "valid pattern - with keyword sentrytoken", + input: validPattern, + want: []string{token}, + }, + { + name: "valid pattern - ignore duplicate", + input: fmt.Sprintf("%s token = '%s' | '%s'", keyword, validPattern, validPattern), + want: []string{token}, + }, + { + name: "invalid pattern", + input: fmt.Sprintf("%s = '%s'", keyword, invalidPattern), + want: []string{}, + }, + } + + for _, test := range tests { + 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) + return + } + + results, err := d.FromData(context.Background(), false, []byte(test.input)) + if err != nil { + t.Errorf("error = %v", err) + return + } + + 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)) + } + 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/engine/defaults/defaults.go b/pkg/engine/defaults/defaults.go index d2acbdca4793..b68bc9cca540 100644 --- a/pkg/engine/defaults/defaults.go +++ b/pkg/engine/defaults/defaults.go @@ -624,7 +624,8 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sendbirdorganizationapi" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sendgrid" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sendinbluev2" - "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sentrytoken" + sentrytokenv1 "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sentrytoken/v1" + sentrytokenv2 "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sentrytoken/v2" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/serphouse" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/serpstack" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sheety" @@ -1467,7 +1468,8 @@ func buildDetectorList() []detectors.Detector { &sendbirdorganizationapi.Scanner{}, &sendgrid.Scanner{}, &sendinbluev2.Scanner{}, - &sentrytoken.Scanner{}, + &sentrytokenv1.Scanner{}, + &sentrytokenv2.Scanner{}, &serphouse.Scanner{}, &serpstack.Scanner{}, &sheety.Scanner{}, diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 9cda13599a1d..229280fd381d 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -277,7 +277,7 @@ func TestEngine_DuplicateSecrets(t *testing.T) { // Wait for all the chunks to be processed. assert.Nil(t, e.Finish(ctx)) - want := uint64(5) + want := uint64(2) assert.Equal(t, want, e.GetMetrics().UnverifiedSecretsFound) }