@@ -2,16 +2,18 @@ package testingbot
2
2
3
3
import (
4
4
"context"
5
- regexp "github.com/wasilibs/go-re2"
5
+ "fmt"
6
+ "io"
6
7
"net/http"
7
- "strings"
8
+
9
+ regexp "github.com/wasilibs/go-re2"
8
10
9
11
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
10
12
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
11
13
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
12
14
)
13
15
14
- type Scanner struct {
16
+ type Scanner struct {
15
17
detectors.DefaultMultiPartCredentialProvider
16
18
}
17
19
@@ -36,38 +38,31 @@ func (s Scanner) Keywords() []string {
36
38
func (s Scanner ) FromData (ctx context.Context , verify bool , data []byte ) (results []detectors.Result , err error ) {
37
39
dataStr := string (data )
38
40
39
- matches := keyPat .FindAllStringSubmatch (dataStr , - 1 )
40
- idmatches := idPat .FindAllStringSubmatch (dataStr , - 1 )
41
+ uniqueIDMatches , uniqueKeyMatches := make (map [string ]struct {}), make (map [string ]struct {})
41
42
42
- for _ , match := range matches {
43
- if len (match ) != 2 {
44
- continue
45
- }
46
- resMatch := strings .TrimSpace (match [1 ])
47
- for _ , idmatch := range idmatches {
48
- if len (idmatch ) != 2 {
43
+ for _ , match := range idPat .FindAllStringSubmatch (dataStr , - 1 ) {
44
+ uniqueIDMatches [match [1 ]] = struct {}{}
45
+ }
46
+
47
+ for _ , match := range keyPat .FindAllStringSubmatch (dataStr , - 1 ) {
48
+ uniqueKeyMatches [match [1 ]] = struct {}{}
49
+ }
50
+
51
+ for id := range uniqueIDMatches {
52
+ for key := range uniqueKeyMatches {
53
+ if id == key {
49
54
continue
50
55
}
51
- resIdMatch := strings .TrimSpace (idmatch [1 ])
52
56
53
57
s1 := detectors.Result {
54
58
DetectorType : detectorspb .DetectorType_TestingBot ,
55
- Raw : []byte (resMatch ),
59
+ Raw : []byte (key ),
56
60
}
57
61
58
62
if verify {
59
- req , err := http .NewRequestWithContext (ctx , "GET" , "https://api.testingbot.com/v1/user" , nil )
60
- if err != nil {
61
- continue
62
- }
63
- req .SetBasicAuth (resIdMatch , resMatch )
64
- res , err := client .Do (req )
65
- if err == nil {
66
- defer res .Body .Close ()
67
- if res .StatusCode >= 200 && res .StatusCode < 300 {
68
- s1 .Verified = true
69
- }
70
- }
63
+ isVerified , verificationErr := verifyTestingBot (ctx , client , id , key )
64
+ s1 .Verified = isVerified
65
+ s1 .SetVerificationError (verificationErr , key )
71
66
}
72
67
73
68
results = append (results , s1 )
@@ -84,3 +79,30 @@ func (s Scanner) Type() detectorspb.DetectorType {
84
79
func (s Scanner ) Description () string {
85
80
return "TestingBot provides cross-browser testing services. TestingBot credentials can be used to automate tests on various browsers and devices."
86
81
}
82
+
83
+ func verifyTestingBot (ctx context.Context , client * http.Client , id , secret string ) (bool , error ) {
84
+ req , err := http .NewRequestWithContext (ctx , "GET" , "https://api.testingbot.com/v1/user" , nil )
85
+ if err != nil {
86
+ return false , err
87
+ }
88
+
89
+ req .SetBasicAuth (id , secret )
90
+ resp , err := client .Do (req )
91
+ if err != nil {
92
+ return false , err
93
+ }
94
+
95
+ defer func () {
96
+ _ , _ = io .Copy (io .Discard , resp .Body )
97
+ _ = resp .Body .Close ()
98
+ }()
99
+
100
+ switch resp .StatusCode {
101
+ case http .StatusOK :
102
+ return true , nil
103
+ case http .StatusUnauthorized , http .StatusForbidden :
104
+ return false , nil
105
+ default :
106
+ return false , fmt .Errorf ("unexpected status code: %d" , resp .StatusCode )
107
+ }
108
+ }
0 commit comments