Skip to content

Commit

Permalink
fixed api flash detector (#3666)
Browse files Browse the repository at this point in the history
* fixed api flash detector

* close the response body
  • Loading branch information
kashifkhan0771 authored Nov 26, 2024
1 parent 7b3d98d commit a16e5ab
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 37 deletions.
79 changes: 44 additions & 35 deletions pkg/detectors/apiflash/apiflash.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package apiflash
import (
"context"
"fmt"
"io"
"net/http"
"strings"

Expand All @@ -24,7 +25,8 @@ var (

// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apiflash"}) + `\b([a-z0-9]{32})\b`)
urlPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apiflash"}) + `\b([a-zA-Z0-9\S]{21,30})\b`)

urlToCapture = "http://google.com" // a fix constant url to capture to verify the access key
)

// Keywords are used for efficiently pre-filtering chunks.
Expand All @@ -36,43 +38,25 @@ func (s Scanner) Keywords() []string {
// FromData will find and optionally verify Apiflash 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)

for _, match := range matches {
if len(match) != 2 {
continue
uniqueAPIKeys := make(map[string]struct{})
for _, match := range keyPat.FindAllStringSubmatch(dataStr, -1) {
uniqueAPIKeys[strings.TrimSpace(match[1])] = struct{}{}
}

for key := range uniqueAPIKeys {
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apiflash,
Raw: []byte(key),
}
resMatch := strings.TrimSpace(match[1])

for _, urlMatch := range urlMatches {
if len(urlMatch) != 2 {
continue
}

resUrlMatch := strings.TrimSpace(urlMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apiflash,
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resUrlMatch),
}

if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.apiflash.com/v1/urltoimage?url=%s&access_key=%s", resUrlMatch, 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
}
}
}

results = append(results, s1)

if verify {
isVerified, verificationErr := verifyAPIFlash(ctx, client, key)
s1.Verified = isVerified
s1.SetVerificationError(verificationErr, key)
}

results = append(results, s1)
}

return results, nil
Expand All @@ -85,3 +69,28 @@ func (s Scanner) Type() detectorspb.DetectorType {
func (s Scanner) Description() string {
return "Apiflash is a screenshot API service. Apiflash keys can be used to access and utilize the screenshot API service."
}

func verifyAPIFlash(ctx context.Context, client *http.Client, accessKey string) (bool, error) {
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)
if err != nil {
return false, err
}

resp, err := client.Do(req)
if err != nil {
return false, nil
}
defer func() {
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()

switch resp.StatusCode {
case http.StatusOK:
return true, nil
case http.StatusUnauthorized:
return false, nil
default:
return false, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
}
3 changes: 1 addition & 2 deletions pkg/detectors/apiflash/apiflash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
var (
validPattern = `
apiflash_key: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
apiflash_url: abc123XYZ456def789ghijklm
`
invalidPattern = "0123456789Gbcde^0123456789abcdef"
)
Expand All @@ -31,7 +30,7 @@ func TestApiFlash_Pattern(t *testing.T) {
{
name: "valid pattern",
input: fmt.Sprintf("apiflash credentials: %s", validPattern),
want: []string{"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6abc123XYZ456def789ghijklm"},
want: []string{"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"},
},
{
name: "invalid pattern",
Expand Down

0 comments on commit a16e5ab

Please sign in to comment.