Skip to content

Commit 11ba4ee

Browse files
authored
updated 24 a letter detectors with indeterminate verification error returns (#4061)
1 parent d4add25 commit 11ba4ee

File tree

24 files changed

+1173
-507
lines changed

24 files changed

+1173
-507
lines changed

pkg/detectors/adobeio/adobeio.go

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package adobeio
22

33
import (
44
"context"
5+
"fmt"
6+
"io"
57
"net/http"
6-
"strings"
78

89
regexp "github.com/wasilibs/go-re2"
910

@@ -12,15 +13,16 @@ import (
1213
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
1314
)
1415

15-
type Scanner struct{
16+
type Scanner struct {
17+
client *http.Client
1618
detectors.DefaultMultiPartCredentialProvider
1719
}
1820

1921
// Ensure the Scanner satisfies the interface at compile time.
2022
var _ detectors.Detector = (*Scanner)(nil)
2123

2224
var (
23-
client = common.SaneHttpClient()
25+
defaultClient = common.SaneHttpClient()
2426

2527
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
2628
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"adobe"}) + `\b([a-z0-9]{32})\b`)
@@ -37,34 +39,33 @@ func (s Scanner) Keywords() []string {
3739
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
3840
dataStr := string(data)
3941

40-
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
41-
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
42+
var uniqueKeys, uniqueIds = make(map[string]struct{}), make(map[string]struct{})
4243

43-
for _, match := range matches {
44-
resMatch := strings.TrimSpace(match[1])
45-
for _, idMatch := range idMatches {
46-
resIdMatch := strings.TrimSpace(idMatch[1])
44+
for _, matches := range keyPat.FindAllStringSubmatch(dataStr, -1) {
45+
uniqueKeys[matches[1]] = struct{}{}
46+
}
47+
48+
for _, matches := range idPat.FindAllStringSubmatch(dataStr, -1) {
49+
uniqueIds[matches[1]] = struct{}{}
50+
}
4751

52+
for key := range uniqueKeys {
53+
for id := range uniqueIds {
4854
s1 := detectors.Result{
4955
DetectorType: detectorspb.DetectorType_AdobeIO,
50-
Raw: []byte(resMatch),
51-
RawV2: []byte(resMatch + resIdMatch),
56+
Raw: []byte(key),
57+
RawV2: []byte(key + id),
5258
}
5359

5460
if verify {
55-
req, err := http.NewRequestWithContext(ctx, "GET", "https://stock.adobe.io/Rest/Media/1/Search/Files?locale=en_US%2526search_parameters%255Bwords%255D=kittens", nil)
56-
if err != nil {
57-
continue
58-
}
59-
req.Header.Add("x-api-key", resMatch)
60-
req.Header.Add("x-product", resIdMatch)
61-
res, err := client.Do(req)
62-
if err == nil {
63-
defer res.Body.Close()
64-
if res.StatusCode >= 200 && res.StatusCode < 300 {
65-
s1.Verified = true
66-
}
61+
client := s.client
62+
if client == nil {
63+
client = defaultClient
6764
}
65+
66+
isVerified, verificationErr := verifyAdobeIOSecret(ctx, client, key, id)
67+
s1.Verified = isVerified
68+
s1.SetVerificationError(verificationErr)
6869
}
6970

7071
results = append(results, s1)
@@ -75,6 +76,35 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
7576
return results, nil
7677
}
7778

79+
func verifyAdobeIOSecret(ctx context.Context, client *http.Client, key string, id string) (bool, error) {
80+
url := "https://stock.adobe.io/Rest/Media/1/Search/Files?locale=en_US%2526search_parameters%255Bwords%255D=kittens"
81+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
82+
if err != nil {
83+
return false, err
84+
}
85+
req.Header.Add("x-api-key", key)
86+
req.Header.Add("x-product", id)
87+
88+
res, err := client.Do(req)
89+
if err != nil {
90+
return false, err
91+
}
92+
93+
defer func() {
94+
_, _ = io.Copy(io.Discard, res.Body)
95+
_ = res.Body.Close()
96+
}()
97+
98+
switch res.StatusCode {
99+
case http.StatusOK:
100+
return true, nil
101+
case http.StatusUnauthorized, http.StatusForbidden:
102+
return false, nil
103+
default:
104+
return false, fmt.Errorf("unexpected status code: %d", res.StatusCode)
105+
}
106+
}
107+
78108
func (s Scanner) Type() detectorspb.DetectorType {
79109
return detectorspb.DetectorType_AdobeIO
80110
}

pkg/detectors/airbrakeprojectkey/airbrakeprojectkey.go

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,28 @@ package airbrakeprojectkey
22

33
import (
44
"context"
5-
regexp "github.com/wasilibs/go-re2"
5+
"fmt"
6+
"io"
67
"net/http"
78
"strings"
89

10+
regexp "github.com/wasilibs/go-re2"
11+
912
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
1013
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
1114
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
1215
)
1316

14-
type Scanner struct{
17+
type Scanner struct {
18+
client *http.Client
1519
detectors.DefaultMultiPartCredentialProvider
1620
}
1721

1822
// Ensure the Scanner satisfies the interface at compile time.
1923
var _ detectors.Detector = (*Scanner)(nil)
2024

2125
var (
22-
client = common.SaneHttpClient()
26+
defaultClient = common.SaneHttpClient()
2327

2428
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
2529
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"airbrake"}) + `\b([a-zA-Z-0-9]{32})\b`)
@@ -36,40 +40,36 @@ func (s Scanner) Keywords() []string {
3640
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
3741
dataStr := string(data)
3842

39-
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
40-
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
41-
42-
for _, match := range matches {
43-
resMatch := strings.TrimSpace(match[1])
43+
var uniqueKeys, uniqueIds = make(map[string]struct{}), make(map[string]struct{})
4444

45-
for _, idMatch := range idMatches {
45+
for _, matches := range keyPat.FindAllStringSubmatch(dataStr, -1) {
46+
uniqueKeys[matches[1]] = struct{}{}
47+
}
4648

47-
resIdMatch := strings.TrimSpace(idMatch[1])
49+
for _, matches := range idPat.FindAllStringSubmatch(dataStr, -1) {
50+
uniqueIds[matches[1]] = struct{}{}
51+
}
4852

53+
for key := range uniqueKeys {
54+
for id := range uniqueIds {
4955
s1 := detectors.Result{
5056
DetectorType: detectorspb.DetectorType_AirbrakeProjectKey,
51-
Raw: []byte(resMatch),
52-
RawV2: []byte(resMatch + resIdMatch),
57+
Raw: []byte(key),
58+
RawV2: []byte(key + id),
5359
}
5460
s1.ExtraData = map[string]string{
5561
"rotation_guide": "https://howtorotate.com/docs/tutorials/airbrake/",
5662
}
5763

5864
if verify {
59-
payload := strings.NewReader(`{"environment":"production","username":"john","email":"[email protected]","repository":"https://github.com/airbrake/airbrake","revision":"38748467ea579e7ae64f7815452307c9d05e05c5","version":"v2.0"}`)
60-
61-
req, err := http.NewRequestWithContext(ctx, "POST", "https://api.airbrake.io/api/v4/projects/"+resIdMatch+"/deploys?key="+resMatch, payload)
62-
if err != nil {
63-
continue
64-
}
65-
req.Header.Add("Content-Type", "application/json")
66-
res, err := client.Do(req)
67-
if err == nil {
68-
defer res.Body.Close()
69-
if res.StatusCode >= 200 && res.StatusCode < 300 {
70-
s1.Verified = true
71-
}
65+
client := s.client
66+
if client == nil {
67+
client = defaultClient
7268
}
69+
70+
isVerified, verificationErr := verifyAirbrakeProjectKey(ctx, client, key, id)
71+
s1.Verified = isVerified
72+
s1.SetVerificationError(verificationErr)
7373
}
7474

7575
results = append(results, s1)
@@ -81,6 +81,35 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
8181
return results, nil
8282
}
8383

84+
func verifyAirbrakeProjectKey(ctx context.Context, client *http.Client, key string, id string) (bool, error) {
85+
url := "https://api.airbrake.io/api/v4/projects/" + id + "/deploys?key=" + key
86+
payload := strings.NewReader(`{"environment":"production","username":"john","email":"[email protected]","repository":"https://github.com/airbrake/airbrake","revision":"38748467ea579e7ae64f7815452307c9d05e05c5","version":"v2.0"}`)
87+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, payload)
88+
if err != nil {
89+
return false, err
90+
}
91+
92+
resp, err := client.Do(req)
93+
if err != nil {
94+
return false, err
95+
}
96+
97+
defer func() {
98+
_, _ = io.Copy(io.Discard, resp.Body)
99+
_ = resp.Body.Close()
100+
}()
101+
102+
// handle according to detector API responses.
103+
switch resp.StatusCode {
104+
case http.StatusOK:
105+
return true, nil
106+
case http.StatusUnauthorized, http.StatusForbidden:
107+
return false, nil
108+
default:
109+
return false, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
110+
}
111+
}
112+
84113
func (s Scanner) Type() detectorspb.DetectorType {
85114
return detectorspb.DetectorType_AirbrakeProjectKey
86115
}

pkg/detectors/airbrakeuserkey/airbrakeuserkey.go

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,26 @@ package airbrakeuserkey
22

33
import (
44
"context"
5-
regexp "github.com/wasilibs/go-re2"
5+
"fmt"
6+
"io"
67
"net/http"
7-
"strings"
8+
9+
regexp "github.com/wasilibs/go-re2"
810

911
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
1012
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
1113
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
1214
)
1315

14-
type Scanner struct{}
16+
type Scanner struct {
17+
client *http.Client
18+
}
1519

1620
// Ensure the Scanner satisfies the interface at compile time.
1721
var _ detectors.Detector = (*Scanner)(nil)
1822

1923
var (
20-
client = common.SaneHttpClient()
24+
defaultClient = common.SaneHttpClient()
2125

2226
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
2327
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"airbrake"}) + `\b([a-zA-Z-0-9]{40})\b`)
@@ -33,31 +37,30 @@ func (s Scanner) Keywords() []string {
3337
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
3438
dataStr := string(data)
3539

36-
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
40+
var uniqueKeys = make(map[string]struct{})
3741

38-
for _, match := range matches {
39-
resMatch := strings.TrimSpace(match[1])
42+
for _, matches := range keyPat.FindAllStringSubmatch(dataStr, -1) {
43+
uniqueKeys[matches[1]] = struct{}{}
44+
}
4045

46+
for key := range uniqueKeys {
4147
s1 := detectors.Result{
4248
DetectorType: detectorspb.DetectorType_AirbrakeUserKey,
43-
Raw: []byte(resMatch),
49+
Raw: []byte(key),
4450
ExtraData: map[string]string{
4551
"rotation_guide": "https://howtorotate.com/docs/tutorials/airbrake/",
4652
},
4753
}
4854

4955
if verify {
50-
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.airbrake.io/api/v4/projects?key="+resMatch, nil)
51-
if err != nil {
52-
continue
53-
}
54-
res, err := client.Do(req)
55-
if err == nil {
56-
defer res.Body.Close()
57-
if res.StatusCode >= 200 && res.StatusCode < 300 {
58-
s1.Verified = true
59-
}
56+
client := s.client
57+
if client == nil {
58+
client = defaultClient
6059
}
60+
61+
isVerified, verificationErr := verifyAirbrakeUserKey(ctx, client, key)
62+
s1.Verified = isVerified
63+
s1.SetVerificationError(verificationErr)
6164
}
6265

6366
results = append(results, s1)
@@ -66,6 +69,31 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
6669
return results, nil
6770
}
6871

72+
func verifyAirbrakeUserKey(ctx context.Context, client *http.Client, key string) (bool, error) {
73+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.airbrake.io/api/v4/projects?key="+key, nil)
74+
if err != nil {
75+
return false, err
76+
}
77+
res, err := client.Do(req)
78+
if err != nil {
79+
return false, err
80+
}
81+
82+
defer func() {
83+
_, _ = io.Copy(io.Discard, res.Body)
84+
_ = res.Body.Close()
85+
}()
86+
87+
switch res.StatusCode {
88+
case http.StatusOK:
89+
return true, nil
90+
case http.StatusUnauthorized, http.StatusForbidden:
91+
return false, nil
92+
default:
93+
return false, fmt.Errorf("unexpected status code: %d", res.StatusCode)
94+
}
95+
}
96+
6997
func (s Scanner) Type() detectorspb.DetectorType {
7098
return detectorspb.DetectorType_AirbrakeUserKey
7199
}

0 commit comments

Comments
 (0)