Skip to content

Commit a16e5ab

Browse files
fixed api flash detector (#3666)
* fixed api flash detector * close the response body
1 parent 7b3d98d commit a16e5ab

File tree

2 files changed

+45
-37
lines changed

2 files changed

+45
-37
lines changed

pkg/detectors/apiflash/apiflash.go

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package apiflash
33
import (
44
"context"
55
"fmt"
6+
"io"
67
"net/http"
78
"strings"
89

@@ -24,7 +25,8 @@ var (
2425

2526
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
2627
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apiflash"}) + `\b([a-z0-9]{32})\b`)
27-
urlPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apiflash"}) + `\b([a-zA-Z0-9\S]{21,30})\b`)
28+
29+
urlToCapture = "http://google.com" // a fix constant url to capture to verify the access key
2830
)
2931

3032
// Keywords are used for efficiently pre-filtering chunks.
@@ -36,43 +38,25 @@ func (s Scanner) Keywords() []string {
3638
// FromData will find and optionally verify Apiflash secrets in a given set of bytes.
3739
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
3840
dataStr := string(data)
39-
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
40-
urlMatches := urlPat.FindAllStringSubmatch(dataStr, -1)
4141

42-
for _, match := range matches {
43-
if len(match) != 2 {
44-
continue
42+
uniqueAPIKeys := make(map[string]struct{})
43+
for _, match := range keyPat.FindAllStringSubmatch(dataStr, -1) {
44+
uniqueAPIKeys[strings.TrimSpace(match[1])] = struct{}{}
45+
}
46+
47+
for key := range uniqueAPIKeys {
48+
s1 := detectors.Result{
49+
DetectorType: detectorspb.DetectorType_Apiflash,
50+
Raw: []byte(key),
4551
}
46-
resMatch := strings.TrimSpace(match[1])
47-
48-
for _, urlMatch := range urlMatches {
49-
if len(urlMatch) != 2 {
50-
continue
51-
}
52-
53-
resUrlMatch := strings.TrimSpace(urlMatch[1])
54-
s1 := detectors.Result{
55-
DetectorType: detectorspb.DetectorType_Apiflash,
56-
Raw: []byte(resMatch),
57-
RawV2: []byte(resMatch + resUrlMatch),
58-
}
59-
60-
if verify {
61-
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.apiflash.com/v1/urltoimage?url=%s&access_key=%s", resUrlMatch, resMatch), nil)
62-
if err != nil {
63-
continue
64-
}
65-
res, err := client.Do(req)
66-
if err == nil {
67-
defer res.Body.Close()
68-
if res.StatusCode >= 200 && res.StatusCode < 300 {
69-
s1.Verified = true
70-
}
71-
}
72-
}
73-
74-
results = append(results, s1)
52+
53+
if verify {
54+
isVerified, verificationErr := verifyAPIFlash(ctx, client, key)
55+
s1.Verified = isVerified
56+
s1.SetVerificationError(verificationErr, key)
7557
}
58+
59+
results = append(results, s1)
7660
}
7761

7862
return results, nil
@@ -85,3 +69,28 @@ func (s Scanner) Type() detectorspb.DetectorType {
8569
func (s Scanner) Description() string {
8670
return "Apiflash is a screenshot API service. Apiflash keys can be used to access and utilize the screenshot API service."
8771
}
72+
73+
func verifyAPIFlash(ctx context.Context, client *http.Client, accessKey string) (bool, error) {
74+
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.apiflash.com/v1/urltoimage?url=%s&access_key=%s&wait_until=page_loaded", urlToCapture, accessKey), http.NoBody)
75+
if err != nil {
76+
return false, err
77+
}
78+
79+
resp, err := client.Do(req)
80+
if err != nil {
81+
return false, nil
82+
}
83+
defer func() {
84+
_, _ = io.Copy(io.Discard, resp.Body)
85+
_ = resp.Body.Close()
86+
}()
87+
88+
switch resp.StatusCode {
89+
case http.StatusOK:
90+
return true, nil
91+
case http.StatusUnauthorized:
92+
return false, nil
93+
default:
94+
return false, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
95+
}
96+
}

pkg/detectors/apiflash/apiflash_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
var (
1515
validPattern = `
1616
apiflash_key: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
17-
apiflash_url: abc123XYZ456def789ghijklm
1817
`
1918
invalidPattern = "0123456789Gbcde^0123456789abcdef"
2019
)
@@ -31,7 +30,7 @@ func TestApiFlash_Pattern(t *testing.T) {
3130
{
3231
name: "valid pattern",
3332
input: fmt.Sprintf("apiflash credentials: %s", validPattern),
34-
want: []string{"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6abc123XYZ456def789ghijklm"},
33+
want: []string{"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"},
3534
},
3635
{
3736
name: "invalid pattern",

0 commit comments

Comments
 (0)