Compare commits

...

1 Commits

Author SHA1 Message Date
Ahrav Dutta 3720609c1f PR 18 of 40 2023-08-25 21:40:42 -07:00
20 changed files with 179 additions and 275 deletions
+7 -9
View File
@@ -52,20 +52,18 @@ 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{"jdbc"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("jdbc")}
}
// FromData will find and optionally verify Jdbc 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)
matches := keyPat.FindAllSubmatch(data, -1)
matchLoop:
for _, match := range matches {
if len(s.ignorePatterns) != 0 {
for _, ignore := range s.ignorePatterns {
if ignore.MatchString(match[0]) {
if ignore.Match(match[0]) {
continue matchLoop
}
}
@@ -75,12 +73,12 @@ matchLoop:
s := detectors.Result{
DetectorType: detectorspb.DetectorType_JDBC,
Raw: []byte(jdbcConn),
Redacted: tryRedactAnonymousJDBC(jdbcConn),
Redacted: tryRedactAnonymousJDBC(string(jdbcConn)),
}
if verify {
s.Verified = false
j, err := newJDBC(jdbcConn)
j, err := newJDBC(string(jdbcConn))
if err != nil {
continue
}
@@ -97,7 +95,7 @@ matchLoop:
// TODO: specialized redaction
}
if !s.Verified && detectors.IsKnownFalsePositive(string(s.Raw), detectors.DefaultFalsePositives, false) {
if !s.Verified && detectors.IsKnownFalsePositive(s.Raw, detectors.DefaultFalsePositives, false) {
continue
}
+2 -1
View File
@@ -3,8 +3,9 @@ package jdbc
import (
"context"
"errors"
"github.com/go-sql-driver/mysql"
"strings"
"github.com/go-sql-driver/mysql"
)
type mysqlJDBC struct {
+2 -1
View File
@@ -4,8 +4,9 @@ import (
"context"
"errors"
"fmt"
"github.com/lib/pq"
"strings"
"github.com/lib/pq"
)
type postgresJDBC struct {
+2 -1
View File
@@ -3,8 +3,9 @@ package jdbc
import (
"context"
"errors"
mssql "github.com/denisenkom/go-mssqldb"
"strings"
mssql "github.com/denisenkom/go-mssqldb"
)
type sqlServerJDBC struct {
+19 -30
View File
@@ -1,12 +1,12 @@
package jiratoken
import (
"bytes"
"context"
b64 "encoding/base64"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -15,13 +15,11 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
tokenPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b([a-zA-Z-0-9]{24})\b`)
domainPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b([a-zA-Z-0-9]{5,24}\.[a-zA-Z-0-9]{3,16}\.[a-zA-Z-0-9]{3,16})\b`)
emailPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`)
@@ -32,59 +30,52 @@ const (
loginReasonHeaderKey = "X-Seraph-LoginReason"
)
// 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{"jira"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("jira")}
}
// FromData will find and optionally verify JiraToken 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)
tokens := tokenPat.FindAllStringSubmatch(dataStr, -1)
domains := domainPat.FindAllStringSubmatch(dataStr, -1)
emails := emailPat.FindAllStringSubmatch(dataStr, -1)
tokens := tokenPat.FindAllSubmatch(data, -1)
domains := domainPat.FindAllSubmatch(data, -1)
emails := emailPat.FindAllSubmatch(data, -1)
for _, email := range emails {
email = strings.Split(email[0], " ")
if len(email) != 2 {
emailSplit := bytes.Split(email[0], []byte(" "))
if len(emailSplit) != 2 {
continue
}
resEmail := strings.TrimSpace(email[1])
for _, token := range tokens {
if len(token) != 2 {
continue
}
resToken := strings.TrimSpace(token[1])
for _, domain := range domains {
if len(domain) != 2 {
continue
}
resDomain := strings.TrimSpace(domain[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_JiraToken,
Raw: []byte(resToken),
RawV2: []byte(fmt.Sprintf("%s:%s:%s", resEmail, resToken, resDomain)),
Raw: token[1],
RawV2: []byte(fmt.Sprintf("%s:%s:%s", string(emailSplit[1]), string(token[1]), string(domain[1]))),
}
if verify {
data := fmt.Sprintf("%s:%s", resEmail, resToken)
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+resDomain+"/rest/api/3/dashboard", nil)
dataEncode := b64.StdEncoding.EncodeToString(append(emailSplit[1], token[1]...))
req, err := http.NewRequestWithContext(ctx, "GET", ("https://" + string(domain[1]) + "/rest/api/3/dashboard"), nil)
if err != nil {
continue
}
req.Header.Add("Accept", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", sEnc))
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", dataEncode))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
// If the request is successful and the login reason is not failed authentication, then the token is valid.
// This is because Jira returns a 200 status code even if the token is invalid.
// Jira returns a default dashboard page.
if (res.StatusCode >= 200 && res.StatusCode < 300) && res.Header.Get(loginReasonHeaderKey) != failedAuth {
s1.Verified = true
}
@@ -92,15 +83,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
if !s1.Verified {
if detectors.IsKnownFalsePositive(string(s1.Raw), detectors.DefaultFalsePositives, true) {
if detectors.IsKnownFalsePositive(s1.Raw, detectors.DefaultFalsePositives, true) {
continue
}
}
results = append(results, s1)
}
}
}
+7 -17
View File
@@ -1,10 +1,10 @@
package jotform
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,52 +13,42 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"jotform"}) + `\b([0-9Aa-z]{32})\b`)
)
// 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{"jotform"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("jotform")}
}
// FromData will find and optionally verify Jotform 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Jotform,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.jotform.com/user?apiKey="+resMatch, nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.jotform.com/user?apiKey="+string(resMatch), nil)
if err != nil {
continue
}
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+9 -11
View File
@@ -1,10 +1,10 @@
package jumpcloud
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -19,30 +19,29 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
// Keeping the regexp patterns unchanged
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jumpcloud"}) + `\b([a-zA-Z0-9]{40})\b`)
)
// 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{"jumpcloud"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("jumpcloud")}
}
// FromData will find and optionally verify Jumpcloud 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Jumpcloud,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
@@ -50,7 +49,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("x-api-key", resMatch)
req.Header.Add("x-api-key", string(resMatch))
res, err := client.Do(req)
if err == nil {
@@ -58,7 +57,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+7 -16
View File
@@ -1,10 +1,10 @@
package juro
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,37 +13,29 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"juro"}) + `\b([a-zA-Z0-9]{40})\b`)
)
// 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{"juro"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("juro")}
}
// FromData will find and optionally verify Juro 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Juro,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
@@ -51,14 +43,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("x-api-key", resMatch)
req.Header.Add("x-api-key", string(resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+11 -15
View File
@@ -1,11 +1,11 @@
package kanban
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,38 +20,33 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"kanban"}) + `\b([0-9A-Z]{12})\b`)
urlPat = regexp.MustCompile(`\b([0-9a-z]{1,}\.kanbantool\.com)\b`)
)
// 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{"kanban"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("kanban")}
}
// FromData will find and optionally verify Kanban 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)
urlMatches := urlPat.FindAllStringSubmatch(dataStr, -1)
matches := keyPat.FindAllSubmatch(data, -1)
urlMatches := urlPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
for _, urlMatch := range urlMatches {
if len(urlMatch) != 2 {
continue
}
resURL := strings.TrimSpace(urlMatch[1])
resURL := bytes.TrimSpace(urlMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Kanban,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
@@ -62,12 +57,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
req.Header.Add("Accept", "application/vnd.kanban+json; version=3")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+12 -11
View File
@@ -1,11 +1,11 @@
package kanbantool
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -27,32 +27,34 @@ 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{"kanbantool"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("kanbantool")}
}
// FromData will find and optionally verify Kanbantool 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.FindAllSubmatch(data, -1)
idMatches := domainPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := domainPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := strings.TrimSpace(idMatch[1])
resIdMatch := bytes.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Kanbantool,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
url := fmt.Sprintf("https://%s.kanbantool.com/api/v3/users/current.json", resIdMatch)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
@@ -66,7 +68,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -75,8 +76,8 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
results = append(results, s1)
}
}
}
return results, nil
+8 -15
View File
@@ -1,11 +1,11 @@
package karmacrm
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,53 +14,46 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"karma"}) + `\b([a-zA-Z0-9]{20})\b`)
)
// 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{"karmacrm"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("karmacrm")}
}
// FromData will find and optionally verify KarmaCRM 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_KarmaCRM,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://app.karmacrm.com/api/v3/contacts.json?api_token=%s&page=1", resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://app.karmacrm.com/api/v3/contacts.json?api_token=%s&page=1", string(resMatch)), nil)
if err != nil {
continue
}
req.Header.Add("Accept", "application/vnd.karmacrm+json; version=3")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+10 -18
View File
@@ -1,10 +1,10 @@
package keenio
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,61 +13,53 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"keen"}) + `\b([0-9A-Z]{64})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"keen"}) + `\b([0-9a-z]{24})\b`)
)
// 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{"keen"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("keen")}
}
// FromData will find and optionally verify KeenIO 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)
idmatches := idPat.FindAllStringSubmatch(dataStr, -1)
matches := keyPat.FindAllSubmatch(data, -1)
idmatches := idPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
for _, idmatch := range idmatches {
if len(idmatch) != 2 {
continue
}
resIdMatch := strings.TrimSpace(idmatch[1])
resIdMatch := bytes.TrimSpace(idmatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_KeenIO,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.keen.io/3.0/organizations/"+resIdMatch+"/projects", nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.keen.io/3.0/organizations/"+string(resIdMatch)+"/projects", nil)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", resMatch)
req.Header.Add("Authorization", string(resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+12 -17
View File
@@ -1,10 +1,11 @@
package kickbox
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,41 +14,33 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"kickbox"}) + `\b([a-zA-Z0-9_]+[a-zA-Z0-9]{64})\b`)
)
// 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{"kickbox"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("kickbox")}
}
// FromData will find and optionally verify Kickbox 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Kickbox,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.kickbox.com/v2/verify?email=kickbox@example.com&apikey="+resMatch, nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.kickbox.com/v2/verify?email=kickbox@example.com&apikey=%s", string(resMatch)), nil)
if err != nil {
continue
}
@@ -57,12 +50,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
}
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
results = append(results, s1)
}
return results, nil
}
+7 -9
View File
@@ -1,10 +1,10 @@
package klipfolio
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -25,25 +25,24 @@ 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{"klipfolio"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("klipfolio")}
}
// FromData will find and optionally verify Klipfolio 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Klipfolio,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
@@ -51,14 +50,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("kf-api-key", resMatch)
req.Header.Add("kf-api-key", string(resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+7 -16
View File
@@ -1,10 +1,10 @@
package knapsackpro
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,37 +13,29 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"knapsackpro"}) + `\b([0-9a-z]{32})\b`)
)
// 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{"knapsackpro"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("knapsackpro")}
}
// FromData will find and optionally verify KnapsackPro 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_KnapsackPro,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
@@ -52,7 +44,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("KNAPSACK-PRO-TEST-SUITE-TOKEN", resMatch)
req.Header.Add("KNAPSACK-PRO-TEST-SUITE-TOKEN", string(resMatch))
res, err := client.Do(req)
if err == nil {
@@ -60,7 +52,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+7 -9
View File
@@ -1,11 +1,11 @@
package kontent
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,25 +26,23 @@ 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{"kontent"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("kontent")}
}
// FromData will find and optionally verify Kontent 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Kontent,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
@@ -52,13 +50,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+12 -21
View File
@@ -1,6 +1,7 @@
package kraken
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha256"
@@ -21,58 +22,49 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
// Bounds have been removed because there are some cases that tokens have trailing frontslash(/) or plus sign (+)
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"kraken"}) + `\b([0-9A-Za-z\/\+=]{56}[ "'\r\n]{1})`)
privKeyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"kraken"}) + `\b([0-9A-Za-z\/\+=]{86,88}[ "'\r\n]{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{"kraken"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("kraken")}
}
// FromData will find and optionally verify Kraken 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)
privKeyMatches := privKeyPat.FindAllStringSubmatch(dataStr, -1)
matches := keyPat.FindAllSubmatch(data, -1)
privKeyMatches := privKeyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
for _, privKeyMatch := range privKeyMatches {
if len(privKeyMatch) != 2 {
continue
}
resPrivKeyMatch := strings.TrimSpace(privKeyMatch[1])
resPrivKeyMatch := bytes.TrimSpace(privKeyMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Kraken,
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resPrivKeyMatch),
Raw: resMatch,
RawV2: append(resMatch, resPrivKeyMatch...),
}
if verify {
// Increasing 64-bit integer, for each request that is made with a particular API key.
apiNonce := strconv.FormatInt(time.Now().Unix(), 10)
payload := url.Values{}
payload.Add("nonce", apiNonce)
b64DecodedSecret, _ := base64.StdEncoding.DecodeString(resPrivKeyMatch)
b64DecodedSecret, _ := base64.StdEncoding.DecodeString(string(resPrivKeyMatch))
signature := getKrakenSignature("/0/private/Balance", payload, b64DecodedSecret)
req, err := http.NewRequestWithContext(ctx, "POST", "https://api.kraken.com/0/private/Balance", strings.NewReader(payload.Encode()))
@@ -80,17 +72,16 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("API-Key", resMatch)
req.Header.Add("API-Key", string(resMatch))
req.Header.Add("API-Sign", signature)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
if !strings.Contains(string(out), "Invalid key") {
if !bytes.Contains(out, []byte("Invalid key")) {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -15
View File
@@ -1,6 +1,7 @@
package kucoin
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha256"
@@ -8,7 +9,6 @@ import (
"net/http"
"regexp"
"strconv"
"strings"
"time"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
@@ -32,40 +32,39 @@ 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{"kucoin"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("kucoin")}
}
// FromData will find and optionally verify KuCoin 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)
keyMatches := keyPat.FindAllStringSubmatch(dataStr, -1)
secretMatches := secretPat.FindAllStringSubmatch(dataStr, -1)
passphraseMatches := passphrasePat.FindAllStringSubmatch(dataStr, -1)
keyMatches := keyPat.FindAllSubmatch(data, -1)
secretMatches := secretPat.FindAllSubmatch(data, -1)
passphraseMatches := passphrasePat.FindAllSubmatch(data, -1)
for _, keyMatch := range keyMatches {
if len(keyMatch) != 2 {
continue
}
resKeyMatch := strings.TrimSpace(keyMatch[1])
resKeyMatch := bytes.TrimSpace(keyMatch[1])
for _, secretMatch := range secretMatches {
if len(secretMatch) != 2 {
continue
}
resSecretMatch := strings.TrimSpace(secretMatch[1])
resSecretMatch := bytes.TrimSpace(secretMatch[1])
for _, passphraseMatch := range passphraseMatches {
if len(passphraseMatch) != 2 {
continue
}
resPassphraseMatch := strings.TrimSpace(passphraseMatch[1])
resPassphraseMatch := bytes.TrimSpace(passphraseMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_KuCoin,
Raw: []byte(resKeyMatch),
RawV2: []byte(resKeyMatch + resPassphraseMatch),
Raw: resKeyMatch,
RawV2: append(resKeyMatch, resPassphraseMatch...),
}
if verify {
@@ -76,14 +75,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
bodyStr := ""
apiVersion := "2"
signature := getKucoinSignature(resSecretMatch, timestamp, method, endpoint, bodyStr)
passPhrase := getKucoinPassphrase(resSecretMatch, resPassphraseMatch)
signature := getKucoinSignature(string(resSecretMatch), timestamp, method, endpoint, bodyStr)
passPhrase := getKucoinPassphrase(string(resSecretMatch), string(resPassphraseMatch))
req, err := http.NewRequest(method, "https://api.kucoin.com"+endpoint, nil)
if err != nil {
continue
}
req.Header.Add("KC-API-KEY", resKeyMatch)
req.Header.Add("KC-API-KEY", string(resKeyMatch))
req.Header.Add("KC-API-SIGN", signature)
req.Header.Add("KC-API-TIMESTAMP", timestamp)
req.Header.Add("KC-API-PASSPHRASE", passPhrase)
+7 -16
View File
@@ -1,10 +1,10 @@
package kylas
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,37 +13,29 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"kylas"}) + `\b([a-z0-9-]{36})\b`)
)
// 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{"kylas"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("kylas")}
}
// FromData will find and optionally verify Kylas 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Kylas,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
@@ -52,14 +44,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("api-key", resMatch)
req.Header.Add("api-key", string(resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+17 -27
View File
@@ -1,12 +1,12 @@
package languagelayer
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -27,56 +27,46 @@ 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{"languagelayer"}
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("languagelayer")}
}
// FromData will find and optionally verify LanguageLayer 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)
matches := keyPat.FindAllSubmatch(data, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])
resMatch := bytes.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_LanguageLayer,
Raw: []byte(resMatch),
Raw: resMatch,
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.languagelayer.com/languages?access_key=%s", resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.languagelayer.com/languages?access_key=%s", string(resMatch)), nil)
if err != nil {
continue
}
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
bodyBytes, err := io.ReadAll(res.Body)
if err == nil {
bodyString := string(bodyBytes)
validResponse := strings.Contains(bodyString, `results`) || strings.Contains(bodyString, `"info":"Access Restricted - Your current Subscription Plan does not support HTTPS Encryption."`)
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
if validResponse {
s1.Verified = true
} else {
s1.Verified = false
}
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
if err == nil && res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = bytes.Contains(bodyBytes, []byte(`results`)) || bytes.Contains(bodyBytes, []byte(`"info":"Access Restricted - Your current Subscription Plan does not support HTTPS Encryption."`))
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
results = append(results, s1)
}
results = append(results, s1)
}
}
return results, nil