diff --git a/pkg/common/patterns.go b/pkg/common/patterns.go index af1c652fb975..774dbf3f6528 100644 --- a/pkg/common/patterns.go +++ b/pkg/common/patterns.go @@ -59,7 +59,6 @@ func (r RegexState) Matches(data []byte) []string { // UsernameRegexCheck constructs an username usernameRegex pattern from a given pattern of excluded characters. func UsernameRegexCheck(pattern string) RegexState { raw := fmt.Sprintf(`(?im)(?:user|usr)\S{0,40}?[:=\s]{1,3}[ '"=]{0,1}([^:%+v]{4,40})\b`, pattern) - fmt.Printf("raw: %s \n", raw) return RegexState{regexp.MustCompile(raw)} } diff --git a/pkg/detectors/snowflake/snowflake.go b/pkg/detectors/snowflake/snowflake.go index 611236e47846..8549cc7c63e6 100644 --- a/pkg/detectors/snowflake/snowflake.go +++ b/pkg/detectors/snowflake/snowflake.go @@ -8,7 +8,6 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" - "log" "net/http" "regexp" "strings" @@ -71,10 +70,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result accountMatches := accountIdentifierPat.FindAllStringSubmatch(dataStr, -1) - fmt.Println("accountMatches: ", accountMatches) - regexPat := detectors.PrefixRegex([]string{"account"}) + `\b([a-zA-Z]{7}-[0-9a-zA-Z]{7})\b` - fmt.Println("regexPat", regexPat) - usernameRegexState := common.UsernameRegexCheck(usernameExclusionPat) usernameMatches := usernameRegexState.Matches(data) @@ -82,7 +77,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result passwordMatches := passwordRegexState.Matches(data) for _, accountMatch := range accountMatches { - fmt.Println("accountMatch: ", accountMatch) if len(accountMatch) != 2 { continue } @@ -109,46 +103,50 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result } if verify { - config := &gosnowflake.Config{ + _ = &gosnowflake.Config{ Account: resAccountMatch, User: resUsernameMatch, Password: resPasswordMatch, Database: database, } - fmt.Println("config: ", config) // Open a connection to Snowflake db, err := sql.Open("snowflake", uri) // Needs the snowflake driver from gosnowflake + if err != nil { - log.Fatal(err) + s1.VerificationError = fmt.Errorf("unable to open a connection to Snowflake %+v", err) } defer db.Close() err = db.Ping() if err != nil { - log.Fatal(err) - } - - s1.Verified = true - - rows, err := db.Query(retrieveAllDatabasesQuery) - if err != nil { - log.Fatal(err) - } - defer rows.Close() - - var databases []string - for rows.Next() { - var name, createdOn, is_default, isCurrent, origin, owner, comment, option, retention_time, kind string - err := rows.Scan(&createdOn, &name, &is_default, &isCurrent, &origin, &owner, &comment, &option, &retention_time, &kind) + if strings.Contains(err.Error(), "Incorrect username or password was specified") { + s1.Verified = false + } + } else { + rows, err := db.Query(retrieveAllDatabasesQuery) if err != nil { - log.Fatal(err) + s1.VerificationError = fmt.Errorf("unable to query Snowflake to enrich secret ExtraData %+v", err) } - databases = append(databases, name) + defer rows.Close() + + var databases []string + for rows.Next() { + var name, createdOn, isDefault, isCurrent, origin, owner, comment, option, retentionTime, kind string + err := rows.Scan(&createdOn, &name, &isDefault, &isCurrent, &origin, &owner, &comment, &option, &retentionTime, &kind) + if err != nil { + s1.VerificationError = fmt.Errorf("unable to finish querying Snowflake to enrich secret ExtraData %+v", err) + } + databases = append(databases, name) + } + s1.ExtraData["databases"] = strings.Join(databases, ", ") + s1.Verified = true } - fmt.Println(databases) - s1.ExtraData["databases"] = strings.Join(databases, ", ") + } + // This function will check false positives for common test words, but also it will make sure the key appears 'random' enough to be a real key. + if !s1.Verified && detectors.IsKnownFalsePositive(resPasswordMatch, detectors.DefaultFalsePositives, true) { + continue } results = append(results, s1) diff --git a/pkg/detectors/snowflake/snowflake_test.go b/pkg/detectors/snowflake/snowflake_test.go index c089286b9491..3a0bdafca4e3 100644 --- a/pkg/detectors/snowflake/snowflake_test.go +++ b/pkg/detectors/snowflake/snowflake_test.go @@ -77,6 +77,10 @@ func TestSnowflake_FromChunk(t *testing.T) { { DetectorType: detectorspb.DetectorType_Snowflake, Verified: false, + ExtraData: map[string]string{ + "account": "tuacoip-zt74995", + "username": "zubairkhan14", + }, }, }, wantErr: false, @@ -99,13 +103,18 @@ func TestSnowflake_FromChunk(t *testing.T) { s: Scanner{client: common.SaneHttpClientTimeOut(1 * time.Microsecond)}, args: args{ ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a snowflake secret %s within", secret)), + data: []byte(fmt.Sprintf("snowflake: \n account=tuacoip-zt74995 \n username=zubairkhan14 \n password=%s \n database=SNOWFLAKE", secret)), verify: true, }, want: []detectors.Result{ { DetectorType: detectorspb.DetectorType_Snowflake, Verified: false, + ExtraData: map[string]string{ + "account": "tuacoip-zt74995", + "databases": "SNOWFLAKE, SNOWFLAKE_SAMPLE_DATA", + "username": "zubairkhan14", + }, }, }, wantErr: false, @@ -116,7 +125,7 @@ func TestSnowflake_FromChunk(t *testing.T) { s: Scanner{client: common.ConstantResponseHttpClient(404, "")}, args: args{ ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a snowflake secret %s within", secret)), + data: []byte(fmt.Sprintf("snowflake: \n account=tuacoip-zt74995 \n username=zubairkhan14 \n password=%s \n database=SNOWFLAKE", secret)), verify: true, }, want: []detectors.Result{