diff --git a/pkg/detectors/pubnubsubscriptionkey/pubnubsubscriptionkey.go b/pkg/detectors/pubnubsubscriptionkey/pubnubsubscriptionkey.go index b551a253e..ed4beae19 100644 --- a/pkg/detectors/pubnubsubscriptionkey/pubnubsubscriptionkey.go +++ b/pkg/detectors/pubnubsubscriptionkey/pubnubsubscriptionkey.go @@ -2,6 +2,8 @@ package pubnubsubscriptionkey import ( "context" + "fmt" + "io" "net/http" "strings" @@ -45,17 +47,9 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result } if verify { - req, err := http.NewRequestWithContext(ctx, "GET", "https://ps.pndsn.com/v2/objects/"+resMatch+"/uuids", 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 - } - } + isVerified, verificationErr := verifyKey(ctx, client, resMatch) + s1.Verified = isVerified + s1.SetVerificationError(verificationErr) } results = append(results, s1) @@ -71,3 +65,40 @@ func (s Scanner) Type() detectorspb.DetectorType { func (s Scanner) Description() string { return "PubNub is a real-time communication platform. A PubNub Subscription Key allows access to the PubNub API for subscribing to channels and receiving messages." } + +func verifyKey(ctx context.Context, client *http.Client, key string) (bool, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://ps.pndsn.com/v2/objects/"+key+"/uuids", nil) + if err != nil { + return false, err + } + + resp, err := client.Do(req) + if err != nil { + return false, err + } + + defer func() { + _, _ = io.Copy(io.Discard, resp.Body) + _ = resp.Body.Close() + }() + + switch resp.StatusCode { + case http.StatusOK: + return true, nil + case http.StatusForbidden: + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + return false, err + } + + if strings.Contains(string(bodyBytes), "Objects not enabled for this subscriber key.") { + return true, nil + } + + return false, nil + case http.StatusUnauthorized: + return false, nil + default: + return false, fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } +}