Skip to content

Commit

Permalink
Detector-Competition-Feat: Added AppOptics API token detector (truffl…
Browse files Browse the repository at this point in the history
…esecurity#1989)

Co-authored-by: Ahrav Dutta <[email protected]>
  • Loading branch information
fumblehool and ahrav authored Oct 27, 2023
1 parent 4d0a40d commit bf6ece3
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 18 deletions.
96 changes: 96 additions & 0 deletions pkg/detectors/appoptics/appoptics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package appoptics

import (
"context"
b64 "encoding/base64"
"fmt"
"net/http"
"regexp"
"strings"

"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
)

type Scanner struct {
client *http.Client
}

// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)

var (
defaultClient = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"appoptics"}) + `\b([0-9a-zA-Z_-]{71})\b`)
)

// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"appoptics"}
}

// FromData will find and optionally verify Appoptics 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)

for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := strings.TrimSpace(match[1])

s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AppOptics,
Raw: []byte(resMatch),
}

if verify {
client := s.client
if client == nil {
client = defaultClient
}
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.appoptics.com/v1/metrics", nil)
if err != nil {
continue
}

data := fmt.Sprintf("%s:", resMatch)
sEnc := b64.StdEncoding.EncodeToString([]byte(data))

req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", sEnc))

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 {
s1.VerificationError = fmt.Errorf("unexpected HTTP response status %d", res.StatusCode)
}
} else {
s1.VerificationError = err
}
}

// This function will check false positives for common test words, but also it will make sure the key appears 'random' enough to be a real key.
if !s1.Verified && detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}

results = append(results, s1)
}

return results, nil
}

func (s Scanner) Type() detectorspb.DetectorType {
return detectorspb.DetectorType_AppOptics
}
128 changes: 128 additions & 0 deletions pkg/detectors/appoptics/appoptics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//go:build detectors
// +build detectors

package appoptics

import (
"context"
"fmt"
"testing"
"time"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"

"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"

"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
)

func TestAppoptics_FromChunk(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors5")
if err != nil {
t.Fatalf("could not get test secrets from GCP: %s", err)
}
secret := testSecrets.MustGetField("APPOPTICS")
inactiveSecret := testSecrets.MustGetField("APPOPTICS_INACTIVE")

type args struct {
ctx context.Context
data []byte
verify bool
}
tests := []struct {
name string
s Scanner
args args
want []detectors.Result
wantErr bool
wantVerificationErr bool
}{
{
name: "found, verified",
s: Scanner{},
args: args{
ctx: context.Background(),
data: []byte(fmt.Sprintf("You can find a appoptics secret %s within", secret)),
verify: true,
},
want: []detectors.Result{
{
DetectorType: detectorspb.DetectorType_AppOptics,
Verified: true,
},
},
wantErr: false,
wantVerificationErr: false,
},
{
name: "found, unverified",
s: Scanner{},
args: args{
ctx: context.Background(),
data: []byte(fmt.Sprintf("You can find a appoptics secret %s within but not valid", inactiveSecret)), // the secret would satisfy the regex but not pass validation
verify: true,
},
want: []detectors.Result{
{
DetectorType: detectorspb.DetectorType_AppOptics,
Verified: false,
},
},
wantErr: false,
wantVerificationErr: false,
},
{
name: "not found",
s: Scanner{},
args: args{
ctx: context.Background(),
data: []byte("You cannot find the secret within"),
verify: true,
},
want: nil,
wantErr: false,
wantVerificationErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.s.FromData(tt.args.ctx, tt.args.verify, tt.args.data)
if (err != nil) != tt.wantErr {
t.Errorf("Appoptics.FromData() error = %v, wantErr %v", err, tt.wantErr)
return
}
for i := range got {
if len(got[i].Raw) == 0 {
t.Fatalf("no raw secret present: \n %+v", got[i])
}
if (got[i].VerificationError != nil) != tt.wantVerificationErr {
t.Fatalf("wantVerificationError = %v, verification error = %v", tt.wantVerificationErr, got[i].VerificationError)
}
}
ignoreOpts := cmpopts.IgnoreFields(detectors.Result{}, "Raw", "VerificationError")
if diff := cmp.Diff(got, tt.want, ignoreOpts); diff != "" {
t.Errorf("Appoptics.FromData() %s diff: (-got +want)\n%s", tt.name, diff)
}
})
}
}

func BenchmarkFromData(benchmark *testing.B) {
ctx := context.Background()
s := Scanner{}
for name, data := range detectors.MustGetBenchmarkData() {
benchmark.Run(name, func(b *testing.B) {
b.ResetTimer()
for n := 0; n < b.N; n++ {
_, err := s.FromData(ctx, false, data)
if err != nil {
b.Fatal(err)
}
}
})
}
}
33 changes: 17 additions & 16 deletions pkg/engine/defaults.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
package engine

import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/anthropic"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/betterstack"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/envoyapikey"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/huggingface"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ip2location"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/openvpn"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ramp"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/salesforce"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/snowflake"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sourcegraph"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sourcegraphcody"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tailscale"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/trufflehogenterprise"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/voiceflow"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zerotier"

"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/abbysale"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/abuseipdb"
Expand All @@ -43,6 +27,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/amadeus"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ambee"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/amplitudeapikey"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/anthropic"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/anypoint"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/apacta"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/api2cart"
Expand All @@ -57,6 +42,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/appcues"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/appfollow"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/appointedd"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/appoptics"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/appsynergy"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/apptivo"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/artsy"
Expand All @@ -82,6 +68,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/beebole"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/besnappy"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/besttime"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/betterstack"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/billomat"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/bitbar"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/bitcoinaverage"
Expand Down Expand Up @@ -235,6 +222,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/elasticemail"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/enablex"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/enigma"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/envoyapikey"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/etherscan"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ethplorer"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/etsyapikey"
Expand Down Expand Up @@ -330,6 +318,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/host"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/html2pdf"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/hubspotapikey"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/huggingface"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/humanity"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/hunter"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/hybiscus"
Expand All @@ -348,6 +337,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/interseller"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/intrinio"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/invoiceocean"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ip2location"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ipapi"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ipgeolocation"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ipify"
Expand Down Expand Up @@ -471,6 +461,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/opencagedata"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/opengraphr"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/openuv"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/openvpn"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/openweather"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/opsgenie"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/optimizely"
Expand Down Expand Up @@ -532,6 +523,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/qase"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/qualaroo"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/qubole"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ramp"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/rapidapi"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/rawg"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/razorpay"
Expand Down Expand Up @@ -561,6 +553,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/salesblink"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/salescookie"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/salesflare"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/salesforce"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/salesmate"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/satismeterprojectkey"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/satismeterwritekey"
Expand Down Expand Up @@ -618,8 +611,11 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/smartystreets"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/smooch"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/snipcart"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/snowflake"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/snykkey"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sonarcloud"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sourcegraph"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/sourcegraphcody"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/speechtextai"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/splunkobservabilitytoken"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/spoonacular"
Expand Down Expand Up @@ -655,6 +651,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/survicate"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/swell"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/swiftype"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tailscale"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tallyfy"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/tatumio"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/taxjar"
Expand Down Expand Up @@ -690,6 +687,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/travelpayouts"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/travisci"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/trelloapikey"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/trufflehogenterprise"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/twelvedata"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/twilio"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/twist"
Expand Down Expand Up @@ -723,6 +721,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/viewneo"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/virustotal"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/visualcrossing"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/voiceflow"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/voicegain"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/voodoosms"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/vouchery"
Expand Down Expand Up @@ -757,6 +756,7 @@ import (
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zenserp"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zeplin"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zerobounce"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zerotier"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zipapi"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zipbooks"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors/zipcodeapi"
Expand Down Expand Up @@ -1552,6 +1552,7 @@ func DefaultDetectors() []detectors.Detector {
ip2location.Scanner{},
vagrantcloudpersonaltoken.Scanner{},
openvpn.Scanner{},
appoptics.Scanner{},
zerotier.Scanner{},
betterstack.Scanner{},
}
Expand Down
Loading

0 comments on commit bf6ece3

Please sign in to comment.