From 8eeb7e5911a720c9b7120c3d65b523ed221e4640 Mon Sep 17 00:00:00 2001 From: Kashif Khan <70996046+kashifkhan0771@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:59:48 +0500 Subject: [PATCH] fixed issue#3701 (#3711) --- pkg/detectors/eventbrite/eventbrite.go | 84 +++++++++++++++++--------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/pkg/detectors/eventbrite/eventbrite.go b/pkg/detectors/eventbrite/eventbrite.go index 4cbb315ec..56ebb1a13 100644 --- a/pkg/detectors/eventbrite/eventbrite.go +++ b/pkg/detectors/eventbrite/eventbrite.go @@ -2,9 +2,10 @@ package eventbrite import ( "context" + "encoding/json" "fmt" + "io" "net/http" - "strings" regexp "github.com/wasilibs/go-re2" @@ -26,6 +27,14 @@ var ( keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"eventbrite"}) + `\b([0-9A-Z]{20})\b`) ) +func (s *Scanner) getClient() *http.Client { + if s.client == nil { + return defaultClient + } + + return s.client +} + // Keywords are used for efficiently pre-filtering chunks. // Use identifiers in the secret preferably, or the provider name. func (s Scanner) Keywords() []string { @@ -36,42 +45,24 @@ func (s Scanner) Keywords() []string { func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { dataStr := string(data) - matches := keyPat.FindAllStringSubmatch(dataStr, -1) + uniqueTokenMatches := make(map[string]struct{}) - for _, match := range matches { - if len(match) != 2 { - continue - } - resMatch := strings.TrimSpace(match[1]) + for _, match := range keyPat.FindAllStringSubmatch(dataStr, -1) { + uniqueTokenMatches[match[1]] = struct{}{} + } + for token := range uniqueTokenMatches { s1 := detectors.Result{ DetectorType: detectorspb.DetectorType_Eventbrite, - Raw: []byte(resMatch), + Raw: []byte(token), + ExtraData: map[string]string{}, } if verify { - client := s.client - if client == nil { - client = defaultClient - } - req, err := http.NewRequestWithContext(ctx, "GET", "https://www.eventbriteapi.com/v3/users/me/?token="+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 if res.StatusCode == 401 { - // The secret is determinately not verified (nothing to do) - } else { - err = fmt.Errorf("unexpected HTTP response status %d", res.StatusCode) - s1.SetVerificationError(err, resMatch) - } - } else { - s1.SetVerificationError(err, resMatch) - } + extraData, isVerified, verificationErr := verifyEventBrite(ctx, s.getClient(), token) + s1.Verified = isVerified + s1.SetVerificationError(verificationErr) + s1.ExtraData = extraData } results = append(results, s1) @@ -87,3 +78,36 @@ func (s Scanner) Type() detectorspb.DetectorType { func (s Scanner) Description() string { return "Eventbrite is an event management and ticketing website. Eventbrite API keys can be used to access and manage event data." } + +func verifyEventBrite(ctx context.Context, client *http.Client, token string) (map[string]string, bool, error) { + req, err := http.NewRequestWithContext(ctx, "GET", "https://www.eventbriteapi.com/v3/users/me/?token="+token, nil) + if err != nil { + return nil, false, err + } + + resp, err := client.Do(req) + if err != nil { + return nil, false, err + } + + defer func() { + _, _ = io.Copy(io.Discard, resp.Body) + _ = resp.Body.Close() + }() + + switch resp.StatusCode { + case http.StatusOK: + var response map[string]interface{} + if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { + return nil, false, err + } + + userName := response["name"].(string) + + return map[string]string{"user name": userName}, true, nil + case http.StatusUnauthorized, http.StatusForbidden: + return nil, false, nil + default: + return nil, false, fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } +}