Skip to content

Commit

Permalink
feat: add extradata
Browse files Browse the repository at this point in the history
  • Loading branch information
rgmz committed Dec 25, 2024
1 parent d63c63b commit 91fdeb6
Showing 1 changed file with 47 additions and 23 deletions.
70 changes: 47 additions & 23 deletions pkg/detectors/elasticcloud/elasticcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package elasticcloud

import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"

regexp "github.com/wasilibs/go-re2"

Expand All @@ -29,12 +31,10 @@ func (s Scanner) Description() string {
}

func (s Scanner) Keywords() []string {
return []string{"elasticcloud", "elastic-cloud", "essu"}
return []string{"essu_"}
}

var (
defaultClient = common.SaneHttpClient()

keyPat = regexp.MustCompile(`\b(essu_[a-zA-Z0-9+/]{32,}={0,3})`)
)

Expand All @@ -52,42 +52,41 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}

for match := range uniqueMatches {
s1 := detectors.Result{
r := detectors.Result{
DetectorType: detectorspb.DetectorType_ElasticCloud,
Raw: []byte(match),
}

client := defaultClient
if s.client != nil {
client = s.client
}

if verify {

isVerified, verificationErr := verifyAPIKey(ctx, client, match)
s1.Verified = isVerified
s1.SetVerificationError(verificationErr, match)
if s.client == nil {
s.client = common.SaneHttpClient()
}

isVerified, extraData, verificationErr := verifyAPIKey(ctx, s.client, match)
r.Verified = isVerified
r.ExtraData = extraData
r.SetVerificationError(verificationErr, match)
}

results = append(results, s1)
results = append(results, r)
}

return
}

const elasticCloudAPIBaseURL = "https://api.elastic-cloud.com/api/v1"

func verifyAPIKey(ctx context.Context, c *http.Client, key string) (bool, error) {
func verifyAPIKey(ctx context.Context, c *http.Client, key string) (bool, map[string]string, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, elasticCloudAPIBaseURL+"/deployments", nil)
if err != nil {
return false, err
return false, nil, err
}

req.Header.Set("accept", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("ApiKey %s", key))
res, err := c.Do(req)
if err != nil {
return false, err
return false, nil, err
}
defer func() {
_, _ = io.Copy(io.Discard, res.Body)
Expand All @@ -98,15 +97,40 @@ func verifyAPIKey(ctx context.Context, c *http.Client, key string) (bool, error)
// 401 - key is invalid
// 403 - key is valid but does not have access to the deployments endpoint
switch res.StatusCode {
case http.StatusOK, http.StatusForbidden:
body, _ := io.ReadAll(res.Body)
fmt.Printf("Body is: %q\n", string(body))
return true, nil
case http.StatusOK:
var deployRes deploymentsResponse
if err := json.NewDecoder(res.Body).Decode(&deployRes); err != nil {
return false, nil, err
}

var extraData map[string]string
if len(deployRes.Deployments) > 0 {
var names []string
for _, d := range deployRes.Deployments {
names = append(names, d.Name)
}
extraData = map[string]string{
"deployments": strings.Join(names, ","),
}
}
return true, extraData, nil
case http.StatusUnauthorized:
// The secret is determinately not verified (nothing to do)
return false, nil
return false, nil, nil
case http.StatusForbidden:
return true, nil, nil
default:
body, _ := io.ReadAll(res.Body)
return false, fmt.Errorf("unexpected HTTP response status %d, body=%q", res.StatusCode, string(body))
return false, nil, fmt.Errorf("unexpected HTTP response status %d, body=%q", res.StatusCode, string(body))
}
}

// https://www.elastic.co/docs/api/doc/cloud/group/endpoint-deployments
type deploymentsResponse struct {
Deployments []deployment
}

type deployment struct {
Id string `json:"id"`
Name string `json:"name"`
}

0 comments on commit 91fdeb6

Please sign in to comment.