Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 25 additions & 14 deletions pkg/detectors/kraken/kraken_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package kraken
import (
"context"
"fmt"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
Expand All @@ -13,10 +12,15 @@ import (
)

var (
validKeyPattern = "m=MN/0yYJ/5xqpE15JYDJtCFdDF7RDLuiXtTiSF1FU1H9waiub1kgwI= "
invalidKeyPattern = "m=MN/0yYJ/5xqpE15JYDJtCFdDF7RDLuiXtTiSF1FU1H9waiub1kgwI="
validPrivKeyPattern = "Oe1xUe+sNT7F5SboHSpfCubMhJlAaghB3SZ=NMmkIHTSzWVoF3uTOnxv32cgI+WuEDXYS+z5MvX+q9IUJ1cYo=+ "
invalidPrivKeyPattern = "Oe1xUe+sNT7F5SboHSpfCubMhJlAaghB3SZ=NMmkIHTSzWVoF3uTOnxv32cgI+WuEDXYS+z5MvX+q9IUJ1cYo=+"
// Valid base64-encoded API key (56 chars) with trailing space for the regex boundary.
// Realistic Kraken API keys are base64-encoded, so padding (=) only appears at the end.
validKeyPattern = "mz86TyFYqxUxjCWKbGAYP0PD5qyVBh03M5QFW50vKYb/Sz5Oa9C75e5p "
// Invalid: contains a character (!) not in the allowed set [0-9A-Za-z/+=].
invalidKeyPattern = "mz86TyFYqxUxjCWKbGAYP0PD5qyVBh03M5QFW50vKY!/Sz5Oa9C75e5p "
// Valid base64-encoded private key (88 chars) with trailing space.
validPrivKeyPattern = "jsam46Au9OZarsbalvCHJ8uEcIVCxDEe+W5jLoeABWj4wzVnCpJw+9qZk1JLhgwa2m8XeqoGuN/OV1jlcvh+Jw== "
// Invalid: contains a character (!) not in the allowed set.
invalidPrivKeyPattern = "jsam46Au9OZarsbalvCHJ8uEcIVCxDEe+W5jLoeABWj4wzVnCpJw+9qZk1JLhgwa2m8XeqoGuN/OV1jlcvh+!w== "
keyword = "kraken"
)

Expand All @@ -29,19 +33,26 @@ func TestKraken_Pattern(t *testing.T) {
want []string
}{
{
name: "valid pattern - with keyword kraken",
input: fmt.Sprintf("%s '%s' %s '%s'", keyword, validKeyPattern, keyword, validPrivKeyPattern),
want: []string{strings.TrimSpace(validKeyPattern) + strings.TrimSpace(validPrivKeyPattern)},
name: "valid pattern - realistic API credentials",
input: fmt.Sprintf(`kraken api_key = "%s"
kraken api_secret = "%s"`,
validKeyPattern, validPrivKeyPattern),
want: []string{"mz86TyFYqxUxjCWKbGAYP0PD5qyVBh03M5QFW50vKYb/Sz5Oa9C75e5p" +
"jsam46Au9OZarsbalvCHJ8uEcIVCxDEe+W5jLoeABWj4wzVnCpJw+9qZk1JLhgwa2m8XeqoGuN/OV1jlcvh+Jw=="},
},
{
name: "valid pattern - key out of prefix range",
input: fmt.Sprintf("%s keyword is not close to the real key in the data\n key = '%s' domain: '%s'", keyword, validKeyPattern, validPrivKeyPattern),
want: []string{},
name: "valid pattern - key out of prefix range",
input: fmt.Sprintf(
"%s keyword is not close to the real key in the data\n key = '%s' domain: '%s'",
keyword, validKeyPattern, validPrivKeyPattern),
want: []string{},
},
{
name: "invalid pattern",
input: fmt.Sprintf("%s key = '%s' secret = '%s'", keyword, invalidKeyPattern, invalidPrivKeyPattern),
want: []string{},
name: "invalid pattern - bad characters in key and secret",
input: fmt.Sprintf(`kraken api_key = "%s"
kraken api_secret = "%s"`,
invalidKeyPattern, invalidPrivKeyPattern),
want: []string{},
},
}

Expand Down
33 changes: 22 additions & 11 deletions pkg/detectors/netsuite/netsuite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,50 @@ import (
)

var (
validConsumerKey = "3WaMEd0KQtHSU7b24HEd79RZzSpMOfMdMUpIaXjq83DbNHVosCVrEVDxKiEQzT15"
// Realistic NetSuite OAuth 1.0 TBA credentials.
// All credential components are 64-char alphanumeric strings, matching [a-zA-Z0-9]{64}.
validConsumerKey = "3WaMEd0KQtHSU7b24HEd79RZzSpMOfMdMUpIaXjq83DbNHVosCVrEVDxKiEQzT15"
validConsumerSecret = "5BZ70LfNshsJkDya1XaD8bMqtPWlOa2o1yKCk0H2DxnjtoaJKIcAw75GdI6zRaRD"
validTokenKey = "KeYcG56ViFDleXPFJuEQ5CAGSJn7o2WDa5iGvLIvVBqZj5rMkaWFmzkp4bveJa74"
validTokenSecret = "GGQUdyYOGDfDImJWCz4Kufk2GevaIDuVv83kIa9zCRuXIDLB4oh2eVDVPmsaSai2"
// NetSuite account IDs: alphanumeric + underscore/hyphen, 6-15 chars.
// TSTDRV prefix is a common NetSuite sandbox convention.
validAccountID = "TSTDRV_1234"

// Invalid variants: contain '?' which is not in [a-zA-Z0-9].
invalidConsumerKey = "3Wa?Ed0KQtHSU7b24HEd79RZzSpMOfMdMUpIaXjq83DbNHVosCVrEVDxKiEQzT15"
validConsumerSecret = "5BZ70LfNshsJkDya1XaD8bMqtPWlOa2o1yKCk0H2DxnjtoaJKIcAw75GdI6zRaRD"
invalidConsumerSecret = "5BZ70LfNshsJkDya?XaD8bMqtPWlOa2o1yKCk0H2DxnjtoaJKIcAw75GdI6zRaRD"
validTokenKey = "KeYcG56ViFDleXPFJuEQ5CAGSJn7o2WDa5iGvLIvVBqZj5rMkaWFmzkp4bveJa74"
invalidTokenKey = "KeYcG56ViFDleXPFJuEQ5CAGSJn7o2WD?5iGvLIvVBqZj5rMkaWFmzkp4bveJa74"
validTokenSecret = "GGQUdyYOGDfDImJWCz4Kufk2GevaIDuVv83kIa9zCRuXIDLB4oh2eVDVPmsaSai2"
invalidTokenSecret = "GGQUdyYOGDfDImJWCz4Kufk2Ge?aIDuVv83kIa9zCRuXIDLB4oh2eVDVPmsaSai2"
validAccountID = "x1L2_BXo"
invalidAccountID = "x1L2?BXo"
keyword = "netsuite"
inputFormat = `%s id - '%s'

keyword = "netsuite"
// Format that keeps each credential close to its label keyword, matching
// how PrefixRegex works (keyword within 40 chars of the capture group).
inputFormat = `%s id - '%s'
consumer - '%s' consumer - '%s'
token - '%s' token - '%s'`
outputPair1 = validConsumerKey + validConsumerSecret
outputPair2 = validConsumerSecret + validConsumerKey
)

func TestNetsuite_Pattern(t *testing.T) {
d := Scanner{}
ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d})

outputPair1 := validConsumerKey + validConsumerSecret
outputPair2 := validConsumerSecret + validConsumerKey

tests := []struct {
name string
input string
want []string
}{
{
name: "valid pattern - with keyword netsuite",
name: "valid pattern - NetSuite TBA credentials",
input: fmt.Sprintf(inputFormat, keyword, validAccountID, validConsumerKey, validConsumerSecret, validTokenKey, validTokenSecret),
want: []string{outputPair1, outputPair2, outputPair1, outputPair2},
},
{
name: "invalid pattern",
name: "invalid pattern - bad characters in credentials",
input: fmt.Sprintf(inputFormat, keyword, invalidAccountID, invalidConsumerKey, invalidConsumerSecret, invalidTokenKey, invalidTokenSecret),
want: []string{},
},
Expand Down
26 changes: 18 additions & 8 deletions pkg/detectors/viewneo/viewneo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@ import (
)

var (
validPattern = "cZZ32f1UDFCqsSP6uUlFyPLrXnGhgunvxc3jRsTO1mygukFtXxmk3sV0Q4PiGW8TstPPagjg8o3N0Jp25RKDJUOssch6rbSBVPc3R5vsRSa7y00CKKuu6T6N.2oV6hZlvOR7Jm3L6PzRLMbPRburA2FUfRlRLktcCbt2nBX1iyAfdMv8JvCjAhUJHT52PhiAT3ca7FNd5q5ZXAkn87LnuQhc5UHyuwD8gcWstOghUHZ20tcz7SjVuKyWZFgODlW2WczXqHKxaNhWYz4.839QXG7zlPYdYNhfbvQZe1zHr6bbbjIQYUs2q5whTtUWm8tCMWaOtm_DEZ_xKO5RUrajoClRedRiGK0fFAMshDSyAROOa7NXcE4WM_AuURDSif51QmcWY5HRITdd7y639Zc2Sz1kkUz-Ks_Aqe7xy0VUOlA8m4w2A7IfQ2iDtUeAlWIz1vsOihDxWeNqvTj5D5JOQcyRCiCfTfDWptrJCkKsMWMcDNRE773ypzQVn3r6VSVC63UqdT5Et5jpS5C1wFMuJDei5w7t4vPBTbodepVLtEkn4HcuyTEt0m-Rh_LIxMShlL56AeC7bVBNvvRpNMi_YT3wTozsXvAXEDS1bdOcD_MLk7-g8L1FfeBZxTnRfLR81idE4qR7ecTeNgfVvuiddb-IGrIAefADZ_Vzl49E3amY7twA7EqX04lBZiVfZsO1R0BlzsCLqQ10fsleLl-S00R01G1Fn2e2gkEkRkwOfxbA7BdTYJwz3s1m7rC2HmQLyT_-h8qE30fGzWkoq7INPSTmJ0EJOPDRY3TZi7axUSDEjZbF8TwXcD3jFDmaAYD3D4E5NSKnILnacXC-kfGZQcP4bcrPbHa4BoNN3kyt"
invalidPattern = "c?Z32f1UDFCqsSP6uUlFyPLrXnGhgunvxc3jRsTO1mygukFtXxmk3sV0Q4PiGW8TstPPagjg8o3N0Jp25RKDJUOssch6rbSBVPc3R5vsRSa7y00CKKuu6T6N.2oV6hZlvOR7Jm3L6PzRLMbPRburA2FUfRlRLktcCbt2nBX1iyAfdMv8JvCjAhUJHT52PhiAT3ca7FNd5q5ZXAkn87LnuQhc5UHyuwD8gcWstOghUHZ20tcz7SjVuKyWZFgODlW2WczXqHKxaNhWYz4.839QXG7zlPYdYNhfbvQZe1zHr6bbbjIQYUs2q5whTtUWm8tCMWaOtm_DEZ_xKO5RUrajoClRedRiGK0fFAMshDSyAROOa7NXcE4WM_AuURDSif51QmcWY5HRITdd7y639Zc2Sz1kkUz-Ks_Aqe7xy0VUOlA8m4w2A7IfQ2iDtUeAlWIz1vsOihDxWeNqvTj5D5JOQcyRCiCfTfDWptrJCkKsMWMcDNRE773ypzQVn3r6VSVC63UqdT5Et5jpS5C1wFMuJDei5w7t4vPBTbodepVLtEkn4HcuyTEt0m-Rh_LIxMShlL56AeC7bVBNvvRpNMi_YT3wTozsXvAXEDS1bdOcD_MLk7-g8L1FfeBZxTnRfLR81idE4qR7ecTeNgfVvuiddb-IGrIAefADZ_Vzl49E3amY7twA7EqX04lBZiVfZsO1R0BlzsCLqQ10fsleLl-S00R01G1Fn2e2gkEkRkwOfxbA7BdTYJwz3s1m7rC2HmQLyT_-h8qE30fGzWkoq7INPSTmJ0EJOPDRY3TZi7axUSDEjZbF8TwXcD3jFDmaAYD3D4E5NSKnILnacXC-kfGZQcP4bcrPbHa4BoNN3kyt"
keyword = "viewneo"
// Realistic JWT-like viewneo bearer token: header.payload.signature
// Matches the detector pattern: [a-z0-9A-Z]{120,300}.[a-z0-9A-Z]{150,300}.[a-z0-9A-Z-_]{600,800}
validPattern = "NbrnTP3fAbnFbmOHnKYaXRvj7uff0LYTH8xIZM1JRcoreogrNwwmq6OLkTkx9NIQ0Wobtqn62tOy4CqpIqK3yn9FfcgMXAdx9G81aSQHqNgAC72qFl41sNLjVHWGaub52Z" +
".td26fEeVVhDIq2AnHTmt9OBGhnuKoneNo41eoPni6JDWYlgAACTP9gyv1plBArp5B1Id9Z850kEnydx9qWCA79ISjs8JHUdKF0j7elKPoh3pKMzKG5mSoyPstUeC99enq522wjZRL9OaYsP6ihgIqLSmNqE40fAr" +
".aXOqVJBae45I1Ljit5Y35npgX4ANj73-Z4bVv7Z3ZrYg32o0DtYobmv39rPz-I8h-l9qgBUuMGyKqTa7IUVQxeQvu2UttAzsiA8R5NtJasBLPDCnE5YkfGOv0WRombpE2eAOmSFpPaWXgBl9Hdp2DZQ_M85NUG1J5VEqpOXHOresruIioSTeAIAnA5LS2WyawW29AVIMooBbvRzkDiNbzKbPiDdynuWyW1qfbI_wPXPW8mbjiQKnSXkMVh09gbtR9zTeSOgX2Mh-YwBxGv20g9O1TBU9rZIEBUr21f4pDNyb2lnZv4Sra8fUFWSPFYfoStLEHBVvSrqhmhIWlnEU-HsgmolaIr-JSi3F3KECld8E0zeOdjKt_hWMYoHCC3_tNNV8nnQkleaCMsoTSDR7YOQ7BIP60ektVKshSS8GFfcBuqf91K8_RrcWEP6lLOFfwvQ2vSs80JDuu-zG_QIAmxWOWnJ7CSh-MpkJJf_6Dh1FTGr1-pJy6G43rYA7G0stL_FjIwJIDumSKoXcVTZyQ0-FcGL33CHDUAPjE-vSP222yuTW3ceO6_VBgO3CS5cYsxjHKYkf3Np6jDqqaZ5RkCwLOBq2myEpKK_s-QrKRVdMF5sZMwONRUQ1O5PtCLUfsVliI-H61q"

// Invalid: character at position 60 replaced with ? which is not in [a-z0-9A-Z],
// breaking the first segment's {120,300} alphanumeric requirement.
invalidPattern = "NbrnTP3fAbnFbmOHnKYaXRvj7uff0LYTH8xIZM1JRcoreogrNwwmq6OLkT?x9NIQ0Wobtqn62tOy4CqpIqK3yn9FfcgMXAdx9G81aSQHqNgAC72qFl41sNLjVHWGaub52Z" +
".td26fEeVVhDIq2AnHTmt9OBGhnuKoneNo41eoPni6JDWYlgAACTP9gyv1plBArp5B1Id9Z850kEnydx9qWCA79ISjs8JHUdKF0j7elKPoh3pKMzKG5mSoyPstUeC99enq522wjZRL9OaYsP6ihgIqLSmNqE40fAr" +
".aXOqVJBae45I1Ljit5Y35npgX4ANj73-Z4bVv7Z3ZrYg32o0DtYobmv39rPz-I8h-l9qgBUuMGyKqTa7IUVQxeQvu2UttAzsiA8R5NtJasBLPDCnE5YkfGOv0WRombpE2eAOmSFpPaWXgBl9Hdp2DZQ_M85NUG1J5VEqpOXHOresruIioSTeAIAnA5LS2WyawW29AVIMooBbvRzkDiNbzKbPiDdynuWyW1qfbI_wPXPW8mbjiQKnSXkMVh09gbtR9zTeSOgX2Mh-YwBxGv20g9O1TBU9rZIEBUr21f4pDNyb2lnZv4Sra8fUFWSPFYfoStLEHBVvSrqhmhIWlnEU-HsgmolaIr-JSi3F3KECld8E0zeOdjKt_hWMYoHCC3_tNNV8nnQkleaCMsoTSDR7YOQ7BIP60ektVKshSS8GFfcBuqf91K8_RrcWEP6lLOFfwvQ2vSs80JDuu-zG_QIAmxWOWnJ7CSh-MpkJJf_6Dh1FTGr1-pJy6G43rYA7G0stL_FjIwJIDumSKoXcVTZyQ0-FcGL33CHDUAPjE-vSP222yuTW3ceO6_VBgO3CS5cYsxjHKYkf3Np6jDqqaZ5RkCwLOBq2myEpKK_s-QrKRVdMF5sZMwONRUQ1O5PtCLUfsVliI-H61q"

keyword = "viewneo"
)

func TestViewneo_Pattern(t *testing.T) {
Expand All @@ -26,8 +36,8 @@ func TestViewneo_Pattern(t *testing.T) {
want []string
}{
{
name: "valid pattern - with keyword viewneo",
input: fmt.Sprintf("%s token = '%s'", keyword, validPattern),
name: "valid pattern - realistic bearer token in config",
input: fmt.Sprintf("# %s digital signage config\nVIEWNEO_API_TOKEN=\"%s\"", keyword, validPattern),
want: []string{validPattern},
},
{
Expand All @@ -41,9 +51,9 @@ func TestViewneo_Pattern(t *testing.T) {
want: []string{},
},
{
name: "invalid pattern",
input: fmt.Sprintf("%s = '%s'", keyword, invalidPattern),
want: []string{},
name: "invalid pattern - bad character in token",
input: `viewneo token = '` + invalidPattern + `'`,
want: []string{},
},
}

Expand Down