Compare commits

..

1 Commits

Author SHA1 Message Date
Miccah Castorina 1eae96e283 Add RunOnce and ScheduleRunOnce to SourceManager
This allows the manager to run an already initialized source.
2023-08-31 07:36:18 -07:00
639 changed files with 10296 additions and 6760 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
module github.com/trufflesecurity/trufflehog/v3
go 1.21
go 1.20
replace github.com/jpillora/overseer => github.com/trufflesecurity/overseer v1.1.7-custom5
@@ -50,7 +50,6 @@ require (
github.com/joho/godotenv v1.5.1
github.com/jpillora/overseer v1.1.6
github.com/kylelemons/godebug v1.1.0
github.com/launchdarkly/go-server-sdk/v6 v6.1.0
github.com/lib/pq v1.10.9
github.com/lrstanley/bubblezone v0.0.0-20221222153816-e95291e2243e
github.com/mattn/go-isatty v0.0.18
@@ -171,8 +170,8 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gregjones/httpcache v0.0.0-20171119193500-2bcd89a1743f // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/gregjones/httpcache v0.0.0-20171119193500-2bcd89a1743f // indirect
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@@ -193,6 +192,7 @@ require (
github.com/launchdarkly/go-sdk-events/v2 v2.0.1 // indirect
github.com/launchdarkly/go-semver v1.0.2 // indirect
github.com/launchdarkly/go-server-sdk-evaluation/v2 v2.0.2 // indirect
github.com/launchdarkly/go-server-sdk/v6 v6.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
-18
View File
@@ -39,7 +39,6 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 h1:rTnT/Jrcm+figWlYz4Ixzt0SJ
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
@@ -66,7 +65,6 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE=
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4=
github.com/BobuSumisu/aho-corasick v1.0.3 h1:uuf+JHwU9CHP2Vx+wAy6jcksJThhJS9ehR8a+4nPE9g=
github.com/BobuSumisu/aho-corasick v1.0.3/go.mod h1:hm4jLcvZKI2vRF2WDU1N4p/jpWtpOzp3nLmi9AzX/XE=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -95,14 +93,12 @@ github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1L
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/arrow/go/v12 v12.0.1 h1:JsR2+hzYYjgSUkBSaahpqCetqZMr76djX80fF/DiJbg=
github.com/apache/arrow/go/v12 v12.0.1/go.mod h1:weuTY7JvTG/HDPtMQxEUp7pU73vkLWMLpY67QwZ/WWw=
github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY=
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aws/aws-sdk-go v1.44.83 h1:7+Rtc2Eio6EKUNoZeMV/IVxzVrY5oBQcNPtCcgIHYJA=
@@ -241,7 +237,6 @@ github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdf
github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM=
github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -267,7 +262,6 @@ github.com/getsentry/sentry-go v0.22.0 h1:XNX9zKbv7baSEI65l+H1GEJgSeIC1c7EN5kluW
github.com/getsentry/sentry-go v0.22.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
@@ -277,7 +271,6 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmS
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -373,7 +366,6 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -435,7 +427,6 @@ github.com/jpillora/s3 v1.1.4 h1:YCCKDWzb/Ye9EBNd83ATRF/8wPEy0xd43Rezb6u6fzc=
github.com/jpillora/s3 v1.1.4/go.mod h1:yedE603V+crlFi1Kl/5vZJaBu9pUzE9wvKegU/lF2zs=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003 h1:vJ0Snvo+SLMY72r5J4sEfkuE7AFbixEP2qRbEcum/wA=
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003/go.mod h1:zNBxMY8P21owkeogJELCLeHIt+voOSduHYTFUbwRAV8=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
@@ -454,7 +445,6 @@ github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQ
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -477,10 +467,7 @@ github.com/launchdarkly/go-server-sdk-evaluation/v2 v2.0.2 h1:PAM0GvE0nIUBeOkjdi
github.com/launchdarkly/go-server-sdk-evaluation/v2 v2.0.2/go.mod h1:Mztipcz+7ZMatXVun3k/IfPa8IOgUnAqiZawtFh2MRg=
github.com/launchdarkly/go-server-sdk/v6 v6.1.0 h1:pp/VBIon5JNbtSw7ih7I5MXN9mXHfo6T5xikKVy52dI=
github.com/launchdarkly/go-server-sdk/v6 v6.1.0/go.mod h1:3TfS6vNsNksPT4LGeGuGKtT3zTjTbbOsCUK3nrj1neA=
github.com/launchdarkly/go-test-helpers/v2 v2.2.0 h1:L3kGILP/6ewikhzhdNkHy1b5y4zs50LueWenVF0sBbs=
github.com/launchdarkly/go-test-helpers/v2 v2.2.0/go.mod h1:L7+th5govYp5oKU9iN7To5PgznBuIjBPn+ejqKR0avw=
github.com/launchdarkly/go-test-helpers/v3 v3.0.2 h1:rh0085g1rVJM5qIukdaQ8z1XTWZztbJ49vRZuveqiuU=
github.com/launchdarkly/go-test-helpers/v3 v3.0.2/go.mod h1:u2ZvJlc/DDJTFrshWW50tWMZHLVYXofuSHUfTU/eIwM=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lrstanley/bubblezone v0.0.0-20221222153816-e95291e2243e h1:XoxHx8K6ZKoMtjzWOMDuM69LCdjDDsTOtTfWGrT/fns=
@@ -561,7 +548,6 @@ github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChl
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
@@ -640,7 +626,6 @@ github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
github.com/xanzy/go-gitlab v0.88.0 h1:9GHBrxyCUNZZNuAsbJ1NbEH6XAYsKyTn6NfE0wYO5SY=
github.com/xanzy/go-gitlab v0.88.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
@@ -664,7 +649,6 @@ github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGj
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE=
@@ -901,7 +885,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E=
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
@@ -997,7 +980,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+2 -15
View File
@@ -44,18 +44,6 @@ If you think that something should be included outside of these guidelines, plea
- Go 1.17+
- Make
### Adding New Token Formats to an Existing Scanner
In some instances, services will update their token format, requiring a new regex to properly detect secrets in addition to supporting the previous token format. Accomodating this can be done without adding a net-new detector. [We provide a `Versioner` interface](https://github.com/trufflesecurity/trufflehog/blob/e18cfd5e0af1469a9f05b8d5732bcc94c39da49c/pkg/detectors/detectors.go#L30) that can be implemented.
1. Create a copy of the package and append `_v2` to the package and file names. Ex: `<packagename>/` -> `<packagename>_v2`, `<packagename>.go` -> `<packagename>_v2.go`
Note: Be sure to update the tests to reference the new secret values in GSM, or the tests will fail.
2. Implement the `Versioner` interface. [GitHub example implementation.](/pkg/detectors/github_old/github_old.go#L22)
3. Proceed from step 3 of [Creating a new Secret Scanner](#creating-a-new-secret-scanner)
### Creating a new Secret Scanner
1. Identify the Secret Detector name from the [/proto/detectors.proto](/proto/detectors.proto) `DetectorType` enum.
@@ -108,7 +96,7 @@ Do not embed test credentials in the test code. Instead, use GCP Secrets Manager
Note: `/tmp/s` is a valid path on Linux. You will need to change that for Windows or OSX, otherwise you will see an error. On Windows you will also need to install [WSL](https://docs.microsoft.com/en-us/windows/wsl/install).
```bash
gcloud secrets versions access --project trufflehog-testing --secret detectors5 latest > /tmp/s
gcloud secrets versions access --project trufflehog-testing --secret detectors3 latest > /tmp/s
```
2. Add the secret that you need for testing.
@@ -125,9 +113,8 @@ Do not embed test credentials in the test code. Instead, use GCP Secrets Manager
3. Update the secret version with your modification.
```bash
gcloud secrets versions add --project trufflehog-testing detectors5 --data-file /tmp/s
gcloud secrets versions add --project trufflehog-testing detectors3 --data-file /tmp/s
```
Note: We increment the detectors file name `detectors(n+1)` once the previous one exceeds the max size allowed by GSM (65kb).
4. Access the secret value as shown in the [example code](pkg/detectors/heroku/heroku_test.go).
-12
View File
@@ -40,18 +40,6 @@ If you think that something should be included outside of these guidelines, plea
- Go 1.17+
- Make
### Adding New Token Formats to an Existing Scanner
In some instances, services will update their token format, requiring a new regex to properly detect secrets in addition to supporting the previous token format. Accomodating this can be done without adding a net-new detector. [We provide a `Versioner` interface](https://github.com/trufflesecurity/trufflehog/blob/e18cfd5e0af1469a9f05b8d5732bcc94c39da49c/pkg/detectors/detectors.go#L30) that can be implemented.
1. Create a copy of the package and append `_v2` to the package and file names. Ex: `<packagename>/` -> `<packagename>_v2`, `<packagename>.go` -> `<packagename>_v2.go`
Note: Be sure to update the tests to reference the new secret values in GSM, or the tests will fail.
2. Implement the `Versioner` interface. [GitHub example implementation.](/pkg/detectors/github_old/github_old.go#L22)
3. Proceed from step 3 of [Creating a new Secret Scanner](#creating-a-new-secret-scanner)
### Creating a new Secret Scanner
1. Identify the Secret Detector name from the [/proto/detectors.proto](/proto/detectors.proto) `DetectorType` enum. If necessary, run `make protos` when adding new ones.
+3 -8
View File
@@ -8,12 +8,11 @@ import (
"regexp"
"strings"
"golang.org/x/sync/errgroup"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/custom_detectorspb"
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
"golang.org/x/sync/errgroup"
)
// The maximum number of matches from one chunk. This const is used when
@@ -181,12 +180,8 @@ func (c *customRegexWebhook) createResults(ctx context.Context, match map[string
}
}
func (c *customRegexWebhook) Keywords() [][]byte {
keywords := make([][]byte, 0, len(c.GetKeywords()))
for _, keyword := range c.GetKeywords() {
keywords = append(keywords, []byte(keyword))
}
return keywords
func (c *customRegexWebhook) Keywords() []string {
return c.GetKeywords()
}
// productIndices produces a permutation of indices for each length. Example:
+10 -7
View File
@@ -1,10 +1,10 @@
package abbysale
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -25,23 +25,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("abbysale")}
func (s Scanner) Keywords() []string {
return []string{"abbysale"}
}
// FromData will find and optionally verify Abbysale secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Abbysale,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -49,13 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("x-api-key", string(resMatch))
req.Header.Add("x-api-key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+10 -7
View File
@@ -1,11 +1,11 @@
package abstract
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,27 +26,29 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("abstract")}
func (s Scanner) Keywords() []string {
return []string{"abstract"}
}
// FromData will find and optionally verify Abstract secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Abstract,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://exchange-rates.abstractapi.com/v1/live/?api_key=%s&base=USD", string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://exchange-rates.abstractapi.com/v1/live/?api_key=%s&base=USD", resMatch), nil)
if err != nil {
continue
}
@@ -57,6 +59,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+13 -9
View File
@@ -1,12 +1,12 @@
package abuseipdb
import (
"bytes"
"context"
"io"
"net/http"
// "log"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -27,23 +27,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("abuseipdb")}
func (s Scanner) Keywords() []string {
return []string{"abuseipdb"}
}
// FromData will find and optionally verify AbuseIPDB secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AbuseIPDB,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -51,12 +53,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Key", string(resMatch))
req.Header.Add("Key", resMatch)
res, err := client.Do(req)
if err == nil {
bodyBytes, err := io.ReadAll(res.Body)
if err == nil {
validResponse := bytes.Contains(bodyBytes, []byte(`ipAddress`))
bodyString := string(bodyBytes)
validResponse := strings.Contains(bodyString, `ipAddress`)
// errCode := strings.Contains(bodyString, `AbuseIPDB APIv2 Server.`)
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
@@ -66,6 +70,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
s1.Verified = false
}
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -73,7 +78,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
}
}
results = append(results, s1)
}
+10 -7
View File
@@ -1,10 +1,10 @@
package accuweather
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -25,27 +25,29 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("accuweather")}
func (s Scanner) Keywords() []string {
return []string{"accuweather"}
}
// FromData will find and optionally verify Accuweather secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Accuweather,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://dataservice.accuweather.com/locations/v1/cities/autocomplete?apikey="+string(resMatch)+"&q=----&language=en-us", nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://dataservice.accuweather.com/locations/v1/cities/autocomplete?apikey="+resMatch+"&q=----&language=en-us", nil)
if err != nil {
continue
}
@@ -55,6 +57,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+10 -7
View File
@@ -1,10 +1,10 @@
package adafruitio
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -25,27 +25,29 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("aio_")}
func (s Scanner) Keywords() []string {
return []string{"aio_"}
}
// FromData will find and optionally verify AdafruitIO secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AdafruitIO,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://io.adafruit.com/api/v2/ladybugtest/feeds/?x-aio-key="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://io.adafruit.com/api/v2/ladybugtest/feeds/?x-aio-key="+resMatch, nil)
if err != nil {
continue
}
@@ -55,6 +57,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -12
View File
@@ -1,10 +1,10 @@
package adobeio
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,31 +26,32 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("adobe")}
func (s Scanner) Keywords() []string {
return []string{"adobe"}
}
// FromData will find and optionally verify AdobeIO secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AdobeIO,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
@@ -58,14 +59,15 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("x-api-key", string(resMatch))
req.Header.Add("x-product", string(resIdMatch))
req.Header.Add("x-api-key", resMatch)
req.Header.Add("x-product", resIdMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+12 -11
View File
@@ -1,11 +1,11 @@
package adzuna
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -27,35 +27,36 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("adzuna")}
func (s Scanner) Keywords() []string {
return []string{"adzuna"}
}
// FromData will find and optionally verify Adzuna secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Adzuna,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.adzuna.com/v1/api/jobs/gb/search/1?app_id=%s&app_key=%s", string(resIdMatch), string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.adzuna.com/v1/api/jobs/gb/search/1?app_id=%s&app_key=%s", resIdMatch, resMatch), nil)
if err != nil {
continue
}
@@ -65,6 +66,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -74,7 +76,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
results = append(results, s1)
}
}
return results, nil
+14 -11
View File
@@ -1,10 +1,10 @@
package aeroworkflow
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,46 +26,49 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("aeroworkflow")}
func (s Scanner) Keywords() []string {
return []string{"aeroworkflow"}
}
// FromData will find and optionally verify Aeroworkflow secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idmatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idmatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idmatch := range idmatches {
if len(idmatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idmatch[1])
resIdMatch := strings.TrimSpace(idmatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Aeroworkflow,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
req, err := http.NewRequest("GET", "https://api.aeroworkflow.com/api/"+string(resIdMatch)+"/v1/AeroAppointments", nil)
req, err := http.NewRequest("GET", "https://api.aeroworkflow.com/api/"+resIdMatch+"/v1/AeroAppointments", nil)
if err != nil {
continue
}
req.Header.Add("Accept", "application/json")
req.Header.Add("apikey", string(resMatch))
req.Header.Add("apikey", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+13 -10
View File
@@ -1,10 +1,10 @@
package agora
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,31 +26,34 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("agora")}
func (s Scanner) Keywords() []string {
return []string{"agora"}
}
// FromData will find and optionally verify Agora secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
secretMatches := secretPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
secretMatches := secretPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, secret := range secretMatches {
if len(secret) != 2 {
continue
}
resSecret := bytes.TrimSpace(secret[1])
resSecret := strings.TrimSpace(secret[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Agora,
Raw: resMatch,
RawV2: append(resMatch, resSecret...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resSecret),
}
if verify {
@@ -58,7 +61,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.SetBasicAuth(string(resSecret), string(resMatch))
req.SetBasicAuth(resSecret, resMatch)
res, err := client.Do(req)
if err == nil {
+9 -7
View File
@@ -1,11 +1,11 @@
package aha
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,23 +26,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("aha")}
func (s Scanner) Keywords() []string {
return []string{"aha"}
}
// FromData will find and optionally verify Aha secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Aha,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -51,7 +53,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Accept", "application/vnd.aha+json; version=3")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
@@ -1,7 +1,6 @@
package airbrakeprojectkey
import (
"bytes"
"context"
"net/http"
"regexp"
@@ -27,36 +26,40 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("airbrake")}
func (s Scanner) Keywords() []string {
return []string{"airbrake"}
}
// FromData will find and optionally verify AirbrakeProjectKey secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AirbrakeProjectKey,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
payload := strings.NewReader(`{"environment":"production","username":"john","email":"john@smith.com","repository":"https://github.com/airbrake/airbrake","revision":"38748467ea579e7ae64f7815452307c9d05e05c5","version":"v2.0"}`)
req, err := http.NewRequestWithContext(ctx, "POST", "https://api.airbrake.io/api/v4/projects/"+string(resIdMatch)+"/deploys?key="+string(resMatch), payload)
req, err := http.NewRequestWithContext(ctx, "POST", "https://api.airbrake.io/api/v4/projects/"+resIdMatch+"/deploys?key="+resMatch, payload)
if err != nil {
continue
}
@@ -71,13 +74,15 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
if !s1.Verified {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
if detectors.IsKnownFalsePositive(string(s1.Raw), detectors.DefaultFalsePositives, true) {
continue
}
}
results = append(results, s1)
}
}
return results, nil
@@ -1,10 +1,10 @@
package airbrakeuserkey
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -25,27 +25,29 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("airbrake")}
func (s Scanner) Keywords() []string {
return []string{"airbrake"}
}
// FromData will find and optionally verify AirbrakeUserKey secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AirbrakeUserKey,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.airbrake.io/api/v4/projects?key="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.airbrake.io/api/v4/projects?key="+resMatch, nil)
if err != nil {
continue
}
+9 -7
View File
@@ -1,11 +1,11 @@
package airship
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,23 +26,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("airship")}
func (s Scanner) Keywords() []string {
return []string{"airship"}
}
// FromData will find and optionally verify Airship secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Airship,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -51,7 +53,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Accept", "application/vnd.urbanairship+json; version=3")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
+14 -12
View File
@@ -1,11 +1,11 @@
package airtableapikey
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,40 +26,42 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("airtable")}
func (s Scanner) Keywords() []string {
return []string{"airtable"}
}
// FromData will find and optionally verify AirtableApiKey secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
appMatches := appPat.FindAllSubmatch(data, -1)
keyMatches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
appMatches := appPat.FindAllStringSubmatch(dataStr, -1)
keyMatches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, keyMatch := range keyMatches {
if len(keyMatch) != 2 {
continue
}
keyRes := bytes.TrimSpace(keyMatch[1])
keyRes := strings.TrimSpace(keyMatch[1])
for _, appMatch := range appMatches {
if len(appMatch) != 2 {
continue
}
appRes := bytes.TrimSpace(appMatch[1])
appRes := strings.TrimSpace(appMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AirtableApiKey,
Redacted: string(appRes),
Raw: keyRes,
RawV2: append(keyRes, appRes...),
Redacted: appRes,
Raw: []byte(keyRes),
RawV2: []byte(keyRes + appRes),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.airtable.com/v0/"+string(appRes)+"/Projects", nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.airtable.com/v0/"+appRes+"/Projects", nil)
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(keyRes)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", keyRes))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
+10 -8
View File
@@ -1,11 +1,11 @@
package airvisual
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,32 +26,34 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("airvisual")}
func (s Scanner) Keywords() []string {
return []string{"airvisual"}
}
// FromData will find and optionally verify AirVisual secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AirVisual,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.airvisual.com/v2/countries?key=%s", string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.airvisual.com/v2/countries?key=%s", resMatch), nil)
if err != nil {
continue
}
req.Header.Add("Accept", "application/vnd.airvisual+json; version=3")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
+9 -7
View File
@@ -1,11 +1,11 @@
package aiven
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,23 +26,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("aiven")}
func (s Scanner) Keywords() []string {
return []string{"aiven"}
}
// FromData will find and optionally verify Aiven secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Aiven,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -50,7 +52,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("aivenv1 %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("aivenv1 %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
+9 -7
View File
@@ -1,11 +1,11 @@
package alchemy
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -27,23 +27,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("alchemy")}
func (s Scanner) Keywords() []string {
return []string{"alchemy"}
}
// FromData will find and optionally verify Alchemy secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Alchemy,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -51,7 +53,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if client == nil {
client = defaultClient
}
req, err := http.NewRequestWithContext(ctx, "GET", "https://eth-mainnet.g.alchemy.com/v2/"+string(resMatch)+"/getNFTs/?owner=vitalik.eth", nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://eth-mainnet.g.alchemy.com/v2/"+resMatch+"/getNFTs/?owner=vitalik.eth", nil)
if err != nil {
continue
}
+10 -8
View File
@@ -1,12 +1,12 @@
package alconost
import (
"bytes"
"context"
b64 "encoding/base64"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -27,28 +27,30 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("alconost")}
func (s Scanner) Keywords() []string {
return []string{"alconost"}
}
// FromData will find and optionally verify Alconost secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Alconost,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
data := append(resMatch, ':')
sEnc := b64.StdEncoding.EncodeToString(data)
data := fmt.Sprintf("%s:", resMatch)
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
req, err := http.NewRequestWithContext(ctx, "GET", "https://nitro.alconost.com/api/v1/account", nil)
if err != nil {
continue
+13 -10
View File
@@ -1,10 +1,10 @@
package alegra
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,32 +26,34 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("alegra")}
func (s Scanner) Keywords() []string {
return []string{"alegra"}
}
// FromData will find and optionally verify Alegra secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
tokenPatMatch := bytes.TrimSpace(match[1])
tokenPatMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
userPatMatch := bytes.TrimSpace(idMatch[1])
userPatMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Alegra,
Raw: tokenPatMatch,
RawV2: append(tokenPatMatch, userPatMatch...),
Raw: []byte(tokenPatMatch),
RawV2: []byte(tokenPatMatch + userPatMatch),
}
if verify {
@@ -59,13 +61,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.SetBasicAuth(string(userPatMatch), string(tokenPatMatch))
req.SetBasicAuth(userPatMatch, tokenPatMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(tokenPatMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,10 +1,10 @@
package aletheiaapi
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"time"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
@@ -14,30 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"aletheiaapi"}) + `\b([A-Z0-9]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("aletheiaapi")}
// 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{"aletheiaapi"}
}
// FromData will find and optionally verify AletheiaApi secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AletheiaApi,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -47,13 +54,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Key", string(resMatch))
req.Header.Add("Key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -1,10 +1,10 @@
package algoliaadminkey
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,54 +13,61 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"algolia"}) + `\b([a-zA-Z0-9]{32})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"algolia"}) + `\b([A-Z0-9]{10})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("algolia")}
// 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{"algolia"}
}
// FromData will find and optionally verify AlgoliaAdminKey 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.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AlgoliaAdminKey,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+string(resIdMatch)+"-dsn.algolia.net/1/keys", nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+resIdMatch+"-dsn.algolia.net/1/keys", nil)
if err != nil {
continue
}
req.Header.Add("X-Algolia-Application-Id", string(resIdMatch))
req.Header.Add("X-Algolia-API-Key", string(resMatch))
req.Header.Add("X-Algolia-Application-Id", resIdMatch)
req.Header.Add("X-Algolia-API-Key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -71,7 +78,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
results = append(results, s1)
}
}
return results, nil
}
+17 -12
View File
@@ -1,7 +1,6 @@
package alibaba
import (
"bytes"
"context"
"crypto/hmac"
"crypto/rand"
@@ -21,17 +20,21 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(`\b([a-zA-Z0-9]{30})\b`)
idPat = regexp.MustCompile(`\b(LTAI[a-zA-Z0-9]{17,21})[\"';\s]*`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("LTAI")}
// 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{"LTAI"}
}
func randString(n int) string {
@@ -50,7 +53,6 @@ func GetSignature(input, key string) string {
h.Write([]byte(input))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func buildStringToSign(method, input string) string {
filter := strings.Replace(input, "+", "%20", -1)
filter = strings.Replace(filter, "%7E", "~", -1)
@@ -59,27 +61,29 @@ func buildStringToSign(method, input string) string {
return filter
}
// FromData will find and optionally verify Alibaba secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Alibaba,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
@@ -89,7 +93,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
dateISO := time.Now().UTC().Format("2006-01-02T15:04:05Z07:00")
params := req.URL.Query()
params.Add("AccessKeyId", string(resIdMatch))
params.Add("AccessKeyId", resIdMatch)
params.Add("Action", "DescribeRegions")
params.Add("Format", "JSON")
params.Add("SignatureMethod", "HMAC-SHA1")
@@ -99,7 +103,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
params.Add("Version", "2014-05-26")
stringToSign := buildStringToSign(req.Method, params.Encode())
signature := GetSignature(stringToSign, string(resMatch)+"&") // Get Signature HMAC SHA1
signature := GetSignature(stringToSign, resMatch+"&") // Get Signature HMAC SHA1
params.Add("Signature", signature)
req.URL.RawQuery = params.Encode()
@@ -118,6 +122,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
}
}
results = append(results, s1)
}
}
+10 -7
View File
@@ -1,10 +1,10 @@
package alienvault
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -25,23 +25,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("alienvault")}
func (s Scanner) Keywords() []string {
return []string{"alienvault"}
}
// FromData will find and optionally verify AlienVault secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AlienVault,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -49,13 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("X-OTX-API-KEY", string(resMatch))
req.Header.Add("X-OTX-API-KEY", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+22 -9
View File
@@ -1,11 +1,12 @@
package allsports
import (
"bytes"
"context"
"io"
"net/http"
// "log"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,33 +15,41 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"allsports"}) + `\b([0-9a-zA-Z]{64})\b`)
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"allsports"}) + `\b([0-9a-z]{64})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("allsports")}
// 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{"allsports"}
}
// FromData will find and optionally verify Allsports secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Allsports,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://apiv2.allsportsapi.com/football/?met=Countries&APIkey="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://apiv2.allsportsapi.com/football/?met=Countries&APIkey="+resMatch, nil)
if err != nil {
continue
}
@@ -51,7 +60,9 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
if bytes.Contains(bodyBytes, []byte("success")) {
body := string(bodyBytes)
if strings.Contains(body, "success") {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
@@ -60,8 +71,10 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
}
}
results = append(results, s1)
}
return results, nil
}
+21 -12
View File
@@ -1,11 +1,11 @@
package amadeus
import (
"bytes"
"context"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,42 +14,49 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
client = 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{"amadeus"}) + `\b([0-9A-Za-z]{32})\b`)
secretPat = regexp.MustCompile(detectors.PrefixRegex([]string{"amadeus"}) + `\b([0-9A-Za-z]{16})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("amadeus")}
// 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{"amadeus"}
}
// FromData will find and optionally verify Amadeus 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.FindAllSubmatch(data, -1)
secretMatches := secretPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
secretMatches := secretPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, secretMatch := range secretMatches {
if len(secretMatch) != 2 {
continue
}
resSecret := bytes.TrimSpace(secretMatch[1])
resSecret := strings.TrimSpace(secretMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Amadeus,
Raw: resMatch,
RawV2: append(resMatch, resSecret...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resSecret),
}
if verify {
payload := bytes.NewReader(append(append([]byte("grant_type=client_credentials&client_id="), resMatch...), append([]byte("&client_secret="), resSecret...)...))
payload := strings.NewReader("grant_type=client_credentials&client_id=" + resMatch + "&client_secret=" + resSecret)
req, err := http.NewRequestWithContext(ctx, "POST", "https://test.api.amadeus.com/v1/security/oauth2/token", payload)
if err != nil {
@@ -63,9 +70,11 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
if res.StatusCode >= 200 && res.StatusCode < 300 && bytes.Contains(bodyBytes, []byte("access_token")) {
body := string(bodyBytes)
if (res.StatusCode >= 200 && res.StatusCode < 300) && strings.Contains(body, "access_token") {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+24 -11
View File
@@ -1,10 +1,10 @@
package ambee
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,27 +13,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"ambee"}) + `\b([0-9a-f]{64})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("ambee")}
// 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{"ambee"}
}
// FromData will find and optionally verify Ambee secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Ambee,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -41,22 +51,25 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("x-api-key", string(resMatch))
req.Header.Add("x-api-key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
results = append(results, s1)
}
return results, nil
}
@@ -1,10 +1,10 @@
package amplitudeapikey
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,40 +13,46 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"amplitude"}) + `\b([0-9a-f]{32})\b`)
secretPat = regexp.MustCompile(detectors.PrefixRegex([]string{"amplitude"}) + `\b([0-9a-f]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("amplitude")}
// 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{"amplitude"}
}
// FromData will find and optionally verify AmplitudeApiKey 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.FindAllSubmatch(data, -1)
secretMatches := secretPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
secretMatches := secretPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, secretMatch := range secretMatches {
if len(secretMatch) != 2 {
continue
}
resSecretMatch := bytes.TrimSpace(secretMatch[1])
resSecretMatch := strings.TrimSpace(secretMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AmplitudeApiKey,
Raw: resMatch,
RawV2: append(resMatch, resSecretMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resSecretMatch),
}
if verify {
@@ -54,13 +60,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.SetBasicAuth(string(resMatch), string(resSecretMatch))
req.SetBasicAuth(resMatch, resSecretMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+19 -11
View File
@@ -1,11 +1,11 @@
package anypoint
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,53 +14,61 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(`\b([0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})\b`)
orgPat = regexp.MustCompile(detectors.PrefixRegex([]string{"org"}) + `\b([0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("anypoint")}
// 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{"anypoint"}
}
// FromData will find and optionally verify Anypoint secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
orgMatches := orgPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
orgMatches := orgPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, orgMatch := range orgMatches {
if len(orgMatch) != 2 {
continue
}
orgRes := bytes.TrimSpace(orgMatch[1])
orgRes := strings.TrimSpace(orgMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Anypoint,
Raw: resMatch,
RawV2: append(resMatch, orgRes...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + orgRes),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://anypoint.mulesoft.com/apiplatform/repository/v2/organizations/%s/apis/by-name?apiName=%s", string(orgRes), ""), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://anypoint.mulesoft.com/apiplatform/repository/v2/organizations/%s/apis/by-name?apiName=%s", orgRes, ""), nil)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer "+string(resMatch))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,11 +1,11 @@
package apacta
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,34 +14,41 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"apacta"}) + `\b([a-z0-9-]{36})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apacta")}
// 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{"apacta"}
}
// FromData will find and optionally verify Apacta secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apacta,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://app.apacta.com/api/v1/time_entries?api_key=%s", string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://app.apacta.com/api/v1/time_entries?api_key=%s", resMatch), nil)
if err != nil {
continue
}
@@ -51,6 +58,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+27 -12
View File
@@ -1,12 +1,13 @@
package api2cart
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -15,33 +16,40 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"api2cart"}) + `\b([0-9a-f]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("api2cart")}
// 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{"api2cart"}
}
// FromData will find and optionally verify Api2Cart secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Api2Cart,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.api2cart.com/v1.1/account.cart.list.json?api_key=%s", string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.api2cart.com/v1.1/account.cart.list.json?api_key=%s", resMatch), nil)
if err != nil {
continue
}
@@ -49,15 +57,22 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
body, errBody := io.ReadAll(res.Body)
var result Response
err := json.NewDecoder(res.Body).Decode(&result)
if err == nil && res.StatusCode >= 200 && res.StatusCode < 300 && result.ReturnCode == 0 {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
if errBody == nil {
if err := json.Unmarshal(body, &result); err != nil {
continue
}
if res.StatusCode >= 200 && res.StatusCode < 300 && result.ReturnCode == 0 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
}
+19 -12
View File
@@ -1,11 +1,11 @@
package apideck
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,40 +14,46 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(`\b(sk_live_[a-z0-9A-Z-]{93})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apideck"}) + `\b([a-z0-9A-Z]{40})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apideck")}
// 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{"apideck"}
}
// FromData will find and optionally verify ApiDeck 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.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idmatch := range idMatches {
if len(idmatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idmatch[1])
resIdMatch := strings.TrimSpace(idmatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_ApiDeck,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
@@ -55,15 +61,16 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("x-apideck-app-id", string(resIdMatch))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("x-apideck-app-id", resIdMatch)
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive([]byte(resMatch), detectors.DefaultFalsePositives, true) {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
+17 -10
View File
@@ -1,11 +1,11 @@
package apiflash
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,43 +14,49 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"apiflash"}) + `\b([a-z0-9]{32})\b`)
urlPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apiflash"}) + `\b([a-zA-Z0-9\S]{21,30})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apiflash")}
// 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{"apiflash"}
}
// 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) {
matches := keyPat.FindAllSubmatch(data, -1)
urlMatches := urlPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
urlMatches := urlPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, urlMatch := range urlMatches {
if len(urlMatch) != 2 {
continue
}
resUrlMatch := bytes.TrimSpace(urlMatch[1])
resUrlMatch := strings.TrimSpace(urlMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apiflash,
Raw: resMatch,
RawV2: append(resMatch, resUrlMatch...),
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", string(resUrlMatch), string(resMatch)), nil)
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
}
@@ -60,6 +66,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+37 -17
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,36 +15,52 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"apifonica"}) + `\b([0-9a-z]{11}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apifonica")}
// 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{"apifonica"}
}
// FromData will find and optionally verify Apifonica secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
tokenMatches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := match[1]
resMatch := strings.TrimSpace(match[1])
for _, tokenMatch := range tokenMatches {
if len(tokenMatch) != 2 {
continue
}
resToken := strings.TrimSpace(tokenMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_ApiFonica,
Raw: resMatch,
}
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_ApiFonica,
Raw: []byte(resMatch),
}
if verify {
data := append(resMatch, []byte(":")...)
sEnc := b64.StdEncoding.EncodeToString(data)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.apifonica.com/v2/accounts", nil)
if err == nil {
if verify {
data := fmt.Sprintf("%s:%s", resMatch, resToken)
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.apifonica.com/v2/accounts", nil)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Basic %s", sEnc))
res, err := client.Do(req)
@@ -51,14 +68,17 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
}
results = append(results, s1)
results = append(results, s1)
}
}
return results, nil
+15 -7
View File
@@ -1,10 +1,10 @@
package apify
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,34 +13,41 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(`\b(apify\_api\_[a-zA-Z-0-9]{36})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apify")}
// 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{"apify"}
}
// FromData will find and optionally verify Apify secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apify,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.apify.com/v2/acts?token="+string(resMatch)+"&my=true&offset=10&limit=99&desc=true", nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.apify.com/v2/acts?token="+resMatch+"&my=true&offset=10&limit=99&desc=true", nil)
if err != nil {
continue
}
@@ -50,6 +57,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+17 -7
View File
@@ -1,10 +1,10 @@
package apilayer
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,42 +13,52 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"apilayer"}) + `\b([a-zA-Z0-9]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apilayer")}
// 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{"apilayer"}
}
// FromData will find and optionally verify Apilayer secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apilayer,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.apilayer.com/number_verification/countries?access_key="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.apilayer.com/number_verification/countries", nil)
if err != nil {
continue
}
req.Header.Add("apikey", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+22 -13
View File
@@ -1,10 +1,11 @@
package apimatic
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"time"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,50 +14,56 @@ import (
type Scanner struct{}
// Ensures Scanner satisfies the interface at compile time.
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Ensure your group is surrounded in boundary characters to reduce false positives.
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apimatic"}) + `\b([a-zA-Z0-9]{3,20}@[a-zA-Z0-9]{2,12}.[a-zA-Z0-9]{2,5})\b`)
passPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apimatic"}) + `\b([a-z0-9-\S]{8,32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apimatic")}
// 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{"apimatic"}
}
// FromData will find and optionally verify APIMatic secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
passMatches := passPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
passMatches := passPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
userPatMatch := bytes.TrimSpace(match[1])
userPatMatch := strings.TrimSpace(match[1])
for _, idMatch := range passMatches {
if len(idMatch) != 2 {
continue
}
passPatMatch := bytes.TrimSpace(idMatch[1])
passPatMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_APIMatic,
Raw: userPatMatch,
RawV2: append(userPatMatch, passPatMatch...),
Raw: []byte(userPatMatch),
RawV2: []byte(userPatMatch + passPatMatch),
}
if verify {
timeout := 10 * time.Second
client.Timeout = timeout
req, err := http.NewRequestWithContext(ctx, "GET", "https://www.apimatic.io/api/code-generations", nil)
if err != nil {
continue
}
req.SetBasicAuth(string(userPatMatch), string(passPatMatch))
req.SetBasicAuth(userPatMatch, passPatMatch)
res, err := client.Do(req)
if err == nil {
@@ -64,12 +71,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(passPatMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
results = append(results, s1)
}
}
+15 -7
View File
@@ -1,11 +1,11 @@
package apiscience
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,30 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"apiscience"}) + `\b([a-bA-Z0-9\S]{22})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apiscience")}
// 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{"apiscience"}
}
// FromData will find and optionally verify ApiScience secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_ApiScience,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -45,13 +52,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+11 -9
View File
@@ -1,11 +1,10 @@
package apitemplate
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,38 +25,41 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apitemplate")}
func (s Scanner) Keywords() []string {
return []string{"apitemplate"}
}
// FromData will find and optionally verify APITemplate secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_APITemplate,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.apitemplate.io/v1/list-templates?api_key=%s", string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.apitemplate.io/v1/list-templates", nil)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("X-API-KEY", string(resMatch))
req.Header.Add("X-API-KEY", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,11 +1,11 @@
package apollo
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,29 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"apollo"}) + `\b([a-zA-Z0-9]{22})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apollo")}
// 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{"apollo"}
}
// FromData will find and optionally verify Apollo secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apollo,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -44,13 +52,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+20 -15
View File
@@ -1,11 +1,11 @@
package appcues
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,59 +20,64 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"appcues"}) + `\b([a-z0-9-]{36})\b`)
userPat = regexp.MustCompile(detectors.PrefixRegex([]string{"appcues"}) + `\b([a-z0-9-]{39})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"appcues"}) + `\b([0-9]{5})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("appcues")}
// 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{"appcues"}
}
// FromData will find and optionally verify Appcues 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)
keyMatches := keyPat.FindAllSubmatch(data, -1)
userMatches := userPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
userMatches := userPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range keyMatches {
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, userMatch := range userMatches {
if len(userMatch) != 2 {
continue
}
resUserMatch := bytes.TrimSpace(userMatch[1])
resUserMatch := strings.TrimSpace(userMatch[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Appcues,
Raw: resMatch,
RawV2: append(resMatch, resUserMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resUserMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.appcues.com/v2/accounts/%s/flows", string(resIdMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.appcues.com/v2/accounts/%s/flows", resIdMatch), nil)
if err != nil {
continue
}
req.SetBasicAuth(string(resUserMatch), string(resMatch))
req.SetBasicAuth(resUserMatch, resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+17 -8
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,35 +15,42 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"appfollow"}) + `\b([0-9A-Za-z]{20})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("appfollow")}
// 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{"appfollow"}
}
// FromData will find and optionally verify Appfollow secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := match[1]
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Appfollow,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
data := append(resMatch, ':')
sEnc := b64.StdEncoding.EncodeToString(data)
data := fmt.Sprintf("%s:", resMatch)
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.appfollow.io/test", nil)
if err != nil {
continue
@@ -54,6 +62,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+27 -14
View File
@@ -1,11 +1,11 @@
package appointedd
import (
"bytes"
"context"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,53 +14,66 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"appointedd"}) + `\b([a-zA-Z0-9=+]{88})`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("appointedd")}
// 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{"appointedd"}
}
// FromData will find and optionally verify appointedd secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Appointedd,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.appointedd.com/v1/availability/slots", nil)
if err != nil {
continue
}
req.Header.Add("X-API-KEY", string(resMatch))
req.Header.Add("X-API-KEY", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
body := string(bodyBytes)
if bodyBytes, err := io.ReadAll(res.Body); err == nil {
if bytes.Contains(bodyBytes, []byte("total")) {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
if strings.Contains(body, "total") {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
results = append(results, s1)
}
return results, nil
}
+17 -8
View File
@@ -1,11 +1,11 @@
package appsynergy
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,34 +14,42 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"appsynergy"}) + `\b([a-z0-9]{64})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("appsynergy")}
// 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{"appsynergy"}
}
// FromData will find and optionally verify AppSynergy secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AppSynergy,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
payload := bytes.NewBuffer([]byte(`{"html":"<html><body><h1>Hello World</h1></body></html>","filename":"HelloWorld.pdf"}`))
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("https://www.appsynergy.com/api?action=HTML2PDF&apiKey=%s", string(resMatch)), payload)
payload := strings.NewReader(`{"html":"<html><body><h1>Hello World</h1></body></html>","filename":"HelloWorld.pdf"}`)
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("https://www.appsynergy.com/api?action=HTML2PDF&apiKey=%s", resMatch), payload)
if err != nil {
continue
}
@@ -51,6 +59,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+22 -14
View File
@@ -1,13 +1,12 @@
package apptivo
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"regexp"
"io/ioutil"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -16,52 +15,60 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"apptivo"}) + `\b([a-z0-9-]{36})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"apptivo"}) + `\b([a-zA-Z0-9-]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("apptivo")}
// 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{"apptivo"}
}
// FromData will find and optionally verify Apptivo secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Apptivo,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.apptivo.com/app/dao/v6/leads?a=getConfigData&apiKey=%s&accessKey=%s", string(resMatch), string(resIdMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.apptivo.com/app/dao/v6/leads?a=getConfigData&apiKey=%s&accessKey=%s", resMatch, resIdMatch), nil)
if err != nil {
continue
}
res, err := client.Do(req)
if err == nil {
bodyBytes, err := ioutil.ReadAll(res.Body)
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
validResponse := bytes.Contains(bodyBytes, []byte(`displayName`))
bodyString := string(bodyBytes)
validResponse := strings.Contains(bodyString, `displayName`)
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
if validResponse {
@@ -70,6 +77,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
s1.Verified = false
}
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+18 -14
View File
@@ -1,10 +1,10 @@
package artifactory
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -19,54 +19,58 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Keep the regexp patterns unchanged
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(`\b([a-zA-Z0-9]{73})`)
URLPat = regexp.MustCompile(`\b([A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])\.jfrog\.io)`)
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("artifactory")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"artifactory"}
}
// FromData will find and optionally verify Artifactory secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
URLmatches := URLPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllSubmatch(data, -1)
var resURLMatch []byte
dataStr := string(data)
URLmatches := URLPat.FindAllStringSubmatch(dataStr, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
resURLMatch := ""
for _, URLmatch := range URLmatches {
if len(URLmatch) != 2 {
continue
}
resURLMatch = bytes.TrimSpace(URLmatch[1])
resURLMatch = strings.TrimSpace(URLmatch[1])
}
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_ArtifactoryAccessToken,
Raw: resMatch,
RawV2: append(resMatch, resURLMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resURLMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+string(resURLMatch)+"/artifactory/api/storageinfo", nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+resURLMatch+"/artifactory/api/storageinfo", nil)
if err != nil {
continue
}
req.Header.Add("X-JFrog-Art-Api", string(resMatch))
req.Header.Add("X-JFrog-Art-Api", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+20 -11
View File
@@ -1,10 +1,10 @@
package artsy
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,44 +13,51 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"artsy"}) + `\b([0-9a-zA-Z]{32})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"artsy"}) + `\b([0-9a-zA-Z]{20})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("artsy")}
// 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{"artsy"}
}
// FromData will find and optionally verify Artsy secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idmatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idmatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idmatch := range idmatches {
if len(idmatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idmatch[1])
resIdMatch := strings.TrimSpace(idmatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Artsy,
Raw: resMatch,
RawV2: append(resMatch, resIdMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "POST", "https://api.artsy.net/api/tokens/xapp_token?client_id="+string(resIdMatch)+"&client_secret="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "POST", "https://api.artsy.net/api/tokens/xapp_token?client_id="+resIdMatch+"&client_secret="+resMatch, nil)
if err != nil {
continue
}
@@ -60,7 +67,8 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(bytes.Join([][]byte{resMatch, resIdMatch}, nil), detectors.DefaultFalsePositives, true) {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
@@ -69,6 +77,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
results = append(results, s1)
}
}
return results, nil
+15 -7
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -19,25 +20,31 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"asana"}) + `\b([a-z\/:0-9]{51})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("asana")}
// 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{"asana"}
}
// FromData will find and optionally verify AsanaOauth secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := match[1]
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AsanaOauth,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -45,13 +52,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil && res.Body != nil {
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -1,11 +1,11 @@
package asanapersonalaccesstoken
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,6 +14,7 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
@@ -22,22 +23,27 @@ var (
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"asana"}) + `\b([0-9]{1,}\/[0-9]{16,}:[A-Za-z0-9]{32,})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("asana")}
// 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{"asana"}
}
// FromData will find and optionally verify AsanaPersonalAccessToken secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AsanaPersonalAccessToken,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -45,13 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+12 -8
View File
@@ -1,10 +1,10 @@
package assemblyai
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -19,28 +19,31 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Keep the regexp patterns unchanged
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"assemblyai"}) + `\b([0-9a-z]{32})\b`)
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("assemblyai")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"assemblyai"}
}
// FromData will find and optionally verify Assemblyai secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AssemblyAI,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -49,13 +52,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", string(resMatch))
req.Header.Add("Authorization", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -9
View File
@@ -1,10 +1,10 @@
package atera
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -18,27 +18,32 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"atera"}) + `\b([0-9a-z]{32})\b`)
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"atera"}) + `\b([[0-9a-z]{32})\b`)
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("atera")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"atera"}
}
// FromData will find and optionally verify Atera secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Atera,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -47,14 +52,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Accept", "application/json")
req.Header.Add("X-API-KEY", string(resMatch))
req.Header.Add("X-API-KEY", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// Consider adding the []byte conversion here if the input also changed to a []byte.
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -8
View File
@@ -1,12 +1,12 @@
package audd
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,26 +26,30 @@ var (
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("audd")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"audd"}
}
// FromData will find and optionally verify Audd secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Audd,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.audd.io/setCallbackUrl/?api_token=%s&url=https://yourwebsite.com/callbacks_handler/", string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.audd.io/setCallbackUrl/?api_token=%s&url=https://yourwebsite.com/callbacks_handler/", resMatch), nil)
if err != nil {
continue
}
@@ -53,8 +57,9 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err == nil {
bodyBytes, err := io.ReadAll(res.Body)
if err == nil {
bodyString := string(bodyBytes)
validResponse := strings.Contains(bodyString, `"status":"success"`)
defer res.Body.Close()
validResponse := bytes.Contains(bodyBytes, []byte(`"status":"success"`))
if res.StatusCode >= 200 && res.StatusCode < 300 {
if validResponse {
s1.Verified = true
@@ -62,6 +67,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
s1.Verified = false
}
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,28 +14,36 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// long jwt token but note this is default 8640000 seconds = 24 hours but could be set to maximum 2592000 seconds = 720 hours = 30 days
// at https://manage.auth0.com/dashboard/us/dev-63memjo3/apis/management/explorer
managementApiTokenPat = regexp.MustCompile(detectors.PrefixRegex([]string{"auth0"}) + `\b(ey[a-zA-Z0-9._-]+)\b`)
domainPat = regexp.MustCompile(`([a-zA-Z0-9\-]{2,16}\.[a-zA-Z0-9_-]{2,3}\.auth0\.com)`)
domainPat = regexp.MustCompile(`([a-zA-Z0-9\-]{2,16}\.[a-zA-Z0-9_-]{2,3}\.auth0\.com)`) // could be part of url
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("auth0")}
// 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{"auth0"}
}
// FromData will find and optionally verify Auth0ManagementApiToken secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
managementApiTokenMatches := managementApiTokenPat.FindAllSubmatch(data, -1)
domainMatches := domainPat.FindAllSubmatch(data, -1)
dataStr := string(data)
managementApiTokenMatches := managementApiTokenPat.FindAllStringSubmatch(dataStr, -1)
domainMatches := domainPat.FindAllStringSubmatch(dataStr, -1)
for _, managementApiTokenMatch := range managementApiTokenMatches {
if len(managementApiTokenMatch) != 2 {
continue
}
managementApiTokenRes := managementApiTokenMatch[1]
managementApiTokenRes := strings.TrimSpace(managementApiTokenMatch[1])
if len(managementApiTokenRes) < 2000 || len(managementApiTokenRes) > 5000 {
continue
}
@@ -43,22 +52,25 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if len(domainMatch) != 2 {
continue
}
domainRes := domainMatch[1]
domainRes := strings.TrimSpace(domainMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Auth0ManagementApiToken,
Redacted: string(domainRes),
Raw: managementApiTokenRes,
RawV2: append(managementApiTokenRes, domainRes...),
Redacted: domainRes,
Raw: []byte(managementApiTokenRes),
RawV2: []byte(managementApiTokenRes + domainRes),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+string(domainRes)+"/api/v2/users", nil)
/*
curl -H "Authorization: Bearer $token" https://domain/api/v2/users
*/
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+domainRes+"/api/v2/users", nil)
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(managementApiTokenRes)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", managementApiTokenRes))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
+31 -17
View File
@@ -1,7 +1,6 @@
package auth0oauth
import (
"bytes"
"context"
"io"
"net/http"
@@ -16,6 +15,7 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
@@ -23,54 +23,64 @@ var (
clientIdPat = regexp.MustCompile(detectors.PrefixRegex([]string{"auth0"}) + `\b([a-zA-Z0-9_-]{32,60})\b`)
clientSecretPat = regexp.MustCompile(`\b([a-zA-Z0-9_-]{64,})\b`)
domainPat = regexp.MustCompile(`\b([a-zA-Z0-9][a-zA-Z0-9._-]*auth0\.com)\b`)
domainPat = regexp.MustCompile(`\b([a-zA-Z0-9][a-zA-Z0-9._-]*auth0\.com)\b`) // could be part of url
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("auth0")}
// 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{"auth0"}
}
// FromData will find and optionally verify Auth0oauth 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)
clientIdMatches := clientIdPat.FindAllSubmatch(data, -1)
clientSecretMatches := clientSecretPat.FindAllSubmatch(data, -1)
domainMatches := domainPat.FindAllSubmatch(data, -1)
clientIdMatches := clientIdPat.FindAllStringSubmatch(dataStr, -1)
clientSecretMatches := clientSecretPat.FindAllStringSubmatch(dataStr, -1)
domainMatches := domainPat.FindAllStringSubmatch(dataStr, -1)
for _, clientIdMatch := range clientIdMatches {
if len(clientIdMatch) != 2 {
continue
}
clientIdRes := bytes.TrimSpace(clientIdMatch[1])
clientIdRes := strings.TrimSpace(clientIdMatch[1])
for _, clientSecretMatch := range clientSecretMatches {
if len(clientSecretMatch) != 2 {
continue
}
clientSecretRes := bytes.TrimSpace(clientSecretMatch[1])
clientSecretRes := strings.TrimSpace(clientSecretMatch[1])
for _, domainMatch := range domainMatches {
if len(domainMatch) != 2 {
continue
}
domainRes := bytes.TrimSpace(domainMatch[1])
domainRes := strings.TrimSpace(domainMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Auth0oauth,
Redacted: string(clientIdRes),
Raw: clientSecretRes,
RawV2: append(clientIdRes, clientSecretRes...),
Redacted: clientIdRes,
Raw: []byte(clientSecretRes),
RawV2: []byte(clientIdRes + clientSecretRes),
}
if verify {
/*
curl --request POST \
--url 'https://YOUR_DOMAIN/oauth/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'grant_type=authorization_code&client_id=W44JmL3qD6LxHeEJyKe9lMuhcwvPOaOq&client_secret=YOUR_CLIENT_SECRET&code=AUTHORIZATION_CODE&redirect_uri=undefined'
*/
data := url.Values{}
data.Set("grant_type", "authorization_code")
data.Set("client_id", string(clientIdRes))
data.Set("client_secret", string(clientSecretRes))
data.Set("client_id", clientIdRes)
data.Set("client_secret", clientSecretRes)
data.Set("code", "AUTHORIZATION_CODE")
data.Set("redirect_uri", "undefined")
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://"+string(domainRes)+"/oauth/token", strings.NewReader(data.Encode()))
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://"+domainRes+"/oauth/token", strings.NewReader(data.Encode())) // URL-encoded payload
if err != nil {
continue
}
@@ -84,7 +94,11 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
body := string(bodyBytes)
if !bytes.Contains(bodyBytes, []byte("access_denied")) {
// if client_id and client_secret is valid -> 403 {"error":"invalid_grant","error_description":"Invalid authorization code"}
// if invalid -> 401 {"error":"access_denied","error_description":"Unauthorized"}
// ingenious!
if !strings.Contains(body, "access_denied") {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(clientIdRes, detectors.DefaultFalsePositives, true) {
+20 -11
View File
@@ -1,11 +1,11 @@
package autodesk
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,41 +14,49 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
client = 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{"autodesk"}) + `\b([0-9A-Za-z]{32})\b`)
secretPat = regexp.MustCompile(detectors.PrefixRegex([]string{"autodesk"}) + `\b([0-9A-Za-z]{16})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("autodesk")}
// 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{"autodesk"}
}
// FromData will find and optionally verify Autodesk secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
secretMatches := secretPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
secretMatches := secretPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, secretMatch := range secretMatches {
if len(secretMatch) != 2 {
continue
}
resSecret := bytes.TrimSpace(secretMatch[1])
resSecret := strings.TrimSpace(secretMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Autodesk,
Raw: resMatch,
RawV2: append(resMatch, resSecret...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resSecret),
}
if verify {
payload := bytes.NewReader([]byte(fmt.Sprintf(`grant_type=client_credentials&client_id=%s&client_secret=%s`, string(resMatch), string(resSecret))))
payload := strings.NewReader(fmt.Sprintf(`grant_type=client_credentials&client_id=%s&client_secret=%s`, resMatch, resSecret))
req, err := http.NewRequestWithContext(ctx, "POST", "https://developer.api.autodesk.com/authentication/v1/authenticate", payload)
if err != nil {
continue
@@ -60,6 +68,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,13 +1,13 @@
package autoklose
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -16,34 +16,41 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"autoklose"}) + `\b([a-zA-Z0-9-]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("autoklose")}
// 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{"autoklose"}
}
// FromData will find and optionally verify Autoklose secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Autoklose,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.autoklose.com/api/campaigns/?api_token=%s", string(resMatch)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.autoklose.com/api/campaigns/?api_token=%s", resMatch), nil)
if err != nil {
continue
}
@@ -61,6 +68,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
s1.Verified = false
}
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,10 +1,10 @@
package autopilot
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,30 +13,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"autopilot"}) + `\b([0-9a-f]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("autopilot")}
// 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{"autopilot"}
}
// FromData will find and optionally verify AutoPilot secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AutoPilot,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -44,13 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("autopilotapikey", string(resMatch))
req.Header.Add("autopilotapikey", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
@@ -1,11 +1,11 @@
package avazapersonalaccesstoken
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,43 +14,53 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
// The number prefix increments for every Personal Access Token created.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"avaza"}) + `\b([0-9]+-[0-9a-f]{40})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("avaza")}
// 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{"avaza"}
}
// FromData will find and optionally verify AvazaPersonalAccessToken secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AvazaPersonalAccessToken,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.avaza.com/api/Account", nil)
req, err := http.NewRequest("GET", "https://api.avaza.com/api/Account", nil)
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,11 +1,12 @@
package aviationstack
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"time"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,31 +21,37 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"aviationstack"}) + `\b([a-z0-9]{32})\b`)
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("aviationstack")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"aviationstack"}
}
// FromData will find and optionally verify AviationStack secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AviationStack,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.aviationstack.com/v1/flights?access_key=%s", string(resMatch)), nil)
timeout := 10 * time.Second
client.Timeout = timeout
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.aviationstack.com/v1/flights?access_key=%s", resMatch), nil)
if err != nil {
continue
}
@@ -54,6 +61,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+23 -173
View File
@@ -1,7 +1,6 @@
package aws
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha256"
@@ -20,8 +19,7 @@ import (
type scanner struct {
verificationClient *http.Client
skipIDs map[string]struct{}
skipIDs map[string]struct{}
}
func New(opts ...func(*scanner)) *scanner {
@@ -63,13 +61,14 @@ var (
falsePositiveSecretCheck = regexp.MustCompile(`[a-f0-9]{40}`)
)
// Returning the keywords as byte arrays
func (s scanner) Keywords() [][]byte {
return [][]byte{
[]byte("AKIA"),
[]byte("ABIA"),
[]byte("ACCA"),
[]byte("ASIA"),
// 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{
"AKIA",
"ABIA",
"ACCA",
"ASIA",
}
}
@@ -88,17 +87,19 @@ func GetHMAC(key []byte, data []byte) []byte {
// FromData will find and optionally verify AWS secrets in a given set of bytes.
func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
idMatches := idPat.FindAllSubmatch(data, -1)
secretMatches := secretPat.FindAllSubmatch(data, -1)
dataStr := string(data)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
secretMatches := secretPat.FindAllStringSubmatch(dataStr, -1)
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIDMatch := bytes.TrimSpace(idMatch[1])
resIDMatch := strings.TrimSpace(idMatch[1])
if s.skipIDs != nil {
if _, ok := s.skipIDs[string(resIDMatch)]; ok {
if _, ok := s.skipIDs[resIDMatch]; ok {
continue
}
}
@@ -107,13 +108,13 @@ func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if len(secretMatch) != 2 {
continue
}
resSecretMatch := bytes.TrimSpace(secretMatch[1])
resSecretMatch := strings.TrimSpace(secretMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_AWS,
Raw: resIDMatch,
Redacted: string(resIDMatch),
RawV2: append(append([]byte(nil), resIDMatch...), resSecretMatch...),
Raw: []byte(resIDMatch),
Redacted: resIDMatch,
RawV2: []byte(resIDMatch + resSecretMatch),
}
if verify {
@@ -145,17 +146,17 @@ func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (result
params.Add("Action", "GetCallerIdentity")
params.Add("Version", "2011-06-15")
params.Add("X-Amz-Algorithm", algorithm)
params.Add("X-Amz-Credential", string(resIDMatch)+"/"+credentialScope)
params.Add("X-Amz-Credential", resIDMatch+"/"+credentialScope)
params.Add("X-Amz-Date", amzDate)
params.Add("X-Amz-Expires", "30")
params.Add("X-Amz-SignedHeaders", signedHeaders)
canonicalQuerystring := params.Encode()
payloadHash := GetHash("") // empty payload
canonicalRequest := string(method) + "\n" + string(canonicalURI) + "\n" + string(canonicalQuerystring) + "\n" + string(canonicalHeaders) + "\n" + string(signedHeaders) + "\n" + string(payloadHash)
canonicalRequest := method + "\n" + canonicalURI + "\n" + canonicalQuerystring + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + payloadHash
// TASK 2: CREATE THE STRING TO SIGN.
stringToSign := string(algorithm) + "\n" + string(amzDate) + "\n" + string(credentialScope) + "\n" + string(GetHash(canonicalRequest))
stringToSign := algorithm + "\n" + amzDate + "\n" + credentialScope + "\n" + GetHash(canonicalRequest)
// TASK 3: CALCULATE THE SIGNATURE.
// https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
@@ -227,7 +228,7 @@ func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
// If the result is unverified and matches something like a git hash, don't include it in the results.
if !s1.Verified && falsePositiveSecretCheck.Match(resSecretMatch) {
if !s1.Verified && falsePositiveSecretCheck.MatchString(resSecretMatch) {
continue
}
@@ -241,157 +242,6 @@ func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (result
return awsCustomCleanResults(results), nil
}
// func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
// idMatches := idPat.FindAllSubmatch(data, -1)
// secretMatches := secretPat.FindAllSubmatch(data, -1)
//
// for _, idMatch := range idMatches {
// if len(idMatch) != 2 {
// continue
// }
// resIDMatch := bytes.TrimSpace(idMatch[1])
//
// if s.skipIDs != nil {
// if _, ok := s.skipIDs[string(resIDMatch)]; ok {
// continue
// }
// }
//
// for _, secretMatch := range secretMatches {
// if len(secretMatch) != 2 {
// continue
// }
// resSecretMatch := bytes.TrimSpace(secretMatch[1])
//
// s1 := detectors.Result{
// DetectorType: detectorspb.DetectorType_AWS,
// Raw: resIDMatch,
// Redacted: string(resIDMatch),
// RawV2: append(append([]byte(nil), resIDMatch...), resSecretMatch...),
// }
//
// if verify {
// // Each string operation is converted into byte operations
//
// method := []byte("GET")
// service := []byte("sts")
// host := []byte("sts.amazonaws.com")
// region := []byte("us-east-1")
// endpoint := []byte("https://sts.amazonaws.com")
// datestamp := []byte(time.Now().UTC().Format("20060102"))
// amzDate := []byte(time.Now().UTC().Format("20060102T150405Z0700"))
//
// req, err := http.NewRequestWithContext(ctx, string(method), string(endpoint), nil)
// if err != nil {
// continue
// }
// req.Header.Set("Accept", "application/json")
//
// // Byte operations for the subsequent string operations
//
// canonicalURI := []byte("/")
// canonicalHeaders := []byte("host:" + string(host) + "\n")
// signedHeaders := []byte("host")
// algorithm := []byte("AWS4-HMAC-SHA256")
// credentialScope := []byte(fmt.Sprintf("%s/%s/%s/aws4_request", datestamp, region, service))
//
// params := req.URL.Query()
// params.Add("Action", "GetCallerIdentity")
// params.Add("Version", "2011-06-15")
// params.Add("X-Amz-Algorithm", string(algorithm))
// params.Add("X-Amz-Credential", string(resIDMatch)+"/"+string(credentialScope))
// params.Add("X-Amz-Date", string(amzDate))
// params.Add("X-Amz-Expires", "30")
// params.Add("X-Amz-SignedHeaders", string(signedHeaders))
//
// canonicalQuerystring := params.Encode()
// payloadHash := GetHash([]byte("")) // empty payload
// canonicalRequest := string(method) + "\n" + string(canonicalURI) + "\n" + string(canonicalQuerystring) + "\n" + string(canonicalHeaders) + "\n" + string(signedHeaders) + "\n" + string(payloadHash)
//
// // TASK 2: CREATE THE STRING TO SIGN.
// stringToSign := string(algorithm) + "\n" + string(amzDate) + "\n" + string(credentialScope) + "\n" + string(GetHash([]byte(canonicalRequest)))
//
// hash := GetHMAC([]byte(fmt.Sprintf("AWS4%s", string(resSecretMatch))), datestamp)
// hash = GetHMAC(hash, region)
// hash = GetHMAC(hash, service)
// hash = GetHMAC(hash, []byte("aws4_request"))
//
// signature2 := GetHMAC(hash, []byte(stringToSign)) // Get Signature HMAC SHA256
// signature := hex.EncodeToString(signature2)
//
// params.Add("X-Amz-Signature", signature)
// req.Header.Add("Content-type", "application/x-www-form-urlencoded; charset=utf-8")
// req.URL.RawQuery = params.Encode()
//
// client := s.verificationClient
// if client == nil {
// client = defaultVerificationClient
// }
// res, err := client.Do(req)
// if err == nil {
//
// if res.StatusCode >= 200 && res.StatusCode < 300 {
// identityInfo := identityRes{}
// err := json.NewDecoder(res.Body).Decode(&identityInfo)
// if err == nil {
// s1.Verified = true
// s1.ExtraData = map[string]string{
// "account": identityInfo.GetCallerIdentityResponse.GetCallerIdentityResult.Account,
// "user_id": identityInfo.GetCallerIdentityResponse.GetCallerIdentityResult.UserID,
// "arn": identityInfo.GetCallerIdentityResponse.GetCallerIdentityResult.Arn,
// }
// } else {
// s1.VerificationError = err
// }
// res.Body.Close()
// } else {
// // 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 detectors.IsKnownFalsePositive(resSecretMatch, detectors.DefaultFalsePositives, true) {
// continue
// }
//
// if res.StatusCode == 403 {
// var body awsErrorResponseBody
// err = json.NewDecoder(res.Body).Decode(&body)
// res.Body.Close()
// if err == nil {
// // All instances of the code I've seen in the wild are PascalCased but this check is
// // case-insensitive out of an abundance of caution
// if strings.EqualFold(body.Error.Code, "InvalidClientTokenId") {
// // determinate failure - nothing to do
// } else {
// // We see a surprising number of false-negative signature mismatch errors here
// // (The official SDK somehow elicits even more than just making the request
// // ourselves)
// s1.VerificationError = fmt.Errorf("request to %v returned status %d with an unexpected reason (%s: %s)", res.Request.URL, res.StatusCode, body.Error.Code, body.Error.Message)
// }
// } else {
// s1.VerificationError = fmt.Errorf("couldn't parse the sts response body (%v)", err)
// }
// } else {
// s1.VerificationError = fmt.Errorf("request to %v returned unexpected status %d", res.Request.URL, res.StatusCode)
// }
// }
// } else {
// s1.VerificationError = err
// }
// }
//
// // If the result is unverified and matches something like a git hash, don't include it in the results.
// if !s1.Verified && falsePositiveSecretCheck.Match(resSecretMatch) {
// continue
// }
//
// results = append(results, s1)
// // If we've found a verified match with this ID, we don't need to look for any more. So move on to the next ID.
// if s1.Verified {
// break
// }
// }
// }
// return awsCustomCleanResults(results), nil
// }
func awsCustomCleanResults(results []detectors.Result) []detectors.Result {
if len(results) == 0 {
return results
+16 -7
View File
@@ -1,10 +1,10 @@
package axonaut
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,29 +13,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"axonaut"}) + `\b([a-z0-9]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("axonaut")}
// 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{"axonaut"}
}
// FromData will find and optionally verify Axonaut secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Axonaut,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -43,13 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("userApiKey", string(resMatch))
req.Header.Add("userApiKey", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -14
View File
@@ -1,10 +1,10 @@
package aylien
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,48 +26,49 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("aylien")}
func (s Scanner) Keywords() []string {
return []string{"aylien"}
}
// FromData will find and optionally verify Aylien secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
newSecret := append(resMatch, resIdMatch...)
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Aylien,
Raw: resMatch,
RawV2: newSecret,
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resIdMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.aylien.com/news/stories", nil)
if err != nil {
continue
}
req.Header.Add("X-AYLIEN-NewsAPI-Application-ID", string(resMatch))
req.Header.Add("X-AYLIEN-NewsAPI-Application-Key", string(resIdMatch))
req.Header.Add("X-AYLIEN-NewsAPI-Application-ID", resIdMatch)
req.Header.Add("X-AYLIEN-NewsAPI-Application-Key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(newSecret, detectors.DefaultFalsePositives, true) {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
+19 -7
View File
@@ -1,11 +1,11 @@
package ayrshare
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,28 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"ayrshare"}) + `\b([A-Z]{7}-[A-Z0-9]{7}-[A-Z0-9]{7}-[A-Z0-9]{7})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("ayrshare")}
// 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{"ayrshare"}
}
// FromData will find and optionally verify Ayrshare secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Ayrshare,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -43,21 +52,24 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
results = append(results, s1)
}
return results, nil
}
+15 -12
View File
@@ -7,6 +7,7 @@ import (
"strings"
"github.com/Azure/go-autorest/autorest/azure/auth"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb"
)
@@ -30,33 +31,35 @@ var (
tenantIDPat = mustFmtPat("tenant_id", idPatFmt)
// TODO: support old patterns
secretPatFmt = `(?i)(%s).{0,20}([a-z0-9_.\-~]{34})`
secretPatFmt = `(?i)(%s).{0,20}([a-z0-9_\.\-~]{34})`
clientSecretPat = mustFmtPat("client_secret", secretPatFmt)
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("azure")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"azure"}
}
// FromData will find and optionally verify Azure secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
clientSecretMatches := clientSecretPat.FindAllSubmatch(data, -1)
dataStr := string(data)
clientSecretMatches := clientSecretPat.FindAllStringSubmatch(dataStr, -1)
for _, clientSecret := range clientSecretMatches {
tenantIDMatches := tenantIDPat.FindAllSubmatch(data, -1)
tenantIDMatches := tenantIDPat.FindAllStringSubmatch(dataStr, -1)
for _, tenantID := range tenantIDMatches {
clientIDMatches := clientIDPat.FindAllSubmatch(data, -1)
clientIDMatches := clientIDPat.FindAllStringSubmatch(dataStr, -1)
for _, clientID := range clientIDMatches {
s := detectors.Result{
DetectorType: detectorspb.DetectorType_Azure,
Raw: clientSecret[2],
RawV2: append(clientID[2], append(clientSecret[2], tenantID[2]...)...),
Redacted: string(clientID[2]),
Raw: []byte(clientSecret[2]),
RawV2: []byte(clientID[2] + clientSecret[2] + tenantID[2]),
Redacted: clientID[2],
}
if verify {
cred := auth.NewClientCredentialsConfig(string(clientID[2]), string(clientSecret[2]), string(tenantID[2]))
cred := auth.NewClientCredentialsConfig(clientID[2], clientSecret[2], tenantID[2])
token, err := cred.ServicePrincipalToken()
if err != nil {
continue
@@ -68,10 +71,10 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}
if !s.Verified {
if detectors.IsKnownFalsePositive([]byte(s.Redacted), detectors.DefaultFalsePositives, true) {
if detectors.IsKnownFalsePositive(s.Redacted, detectors.DefaultFalsePositives, true) {
continue
}
if detectors.IsKnownFalsePositive(s.Raw, detectors.DefaultFalsePositives, true) {
if detectors.IsKnownFalsePositive(string(s.Raw), detectors.DefaultFalsePositives, true) {
continue
}
}
+10 -7
View File
@@ -1,11 +1,11 @@
package bannerbear
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,29 +20,31 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
// Keep the regexp patterns unchanged
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"bannerbear"}) + `\b([0-9a-zA-Z]{22}tt)\b`)
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bannerbear")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"bannerbear"}
}
// FromData will find and optionally verify Bannerbear 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.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Bannerbear,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -57,6 +59,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,11 +1,11 @@
package baremetrics
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,30 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"baremetrics"}) + `\b([a-zA-Z0-9_]{25})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("baremetrics")}
// 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{"baremetrics"}
}
// FromData will find and optionally verify Baremetrics secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Baremetrics,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -45,13 +52,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+23 -8
View File
@@ -1,11 +1,12 @@
package baseapiio
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,30 +15,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"baseapi", "base-api"}) + `\b([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("baseapi"), []byte("base-api")}
// 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{"baseapi", "base-api"}
}
// FromData will find and optionally verify BaseApiIO secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BaseApiIO,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -45,17 +53,24 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if bytes.Contains(resMatch, []byte("items")) {
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
body := string(bodyBytes)
if strings.Contains(body, "items") {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
+12 -8
View File
@@ -1,10 +1,10 @@
package beamer
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -19,27 +19,31 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"beamer"}) + `\b([a-zA-Z0-9_+/]{45}=)`)
)
// Keywords are used for efficiently pre-filtering chunks.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("beamer")}
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() []string {
return []string{"beamer"}
}
// FromData will find and optionally verify Beamer secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Beamer,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -47,14 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Beamer-Api-Key", string(resMatch))
req.Header.Add("Beamer-Api-Key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+16 -10
View File
@@ -1,12 +1,12 @@
package beebole
import (
"bytes"
"context"
b64 "encoding/base64"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -15,50 +15,56 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"beebole"}) + `\b([0-9a-z]{40})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("beebole")}
// 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{"beebole"}
}
// FromData will find and optionally verify Beebole secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Beebole,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
data := fmt.Sprintf("%s:X", string(resMatch))
data := fmt.Sprintf("%s:X", resMatch)
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
payload := bytes.NewReader([]byte(`{"service": "custom_field.list"}`))
payload := strings.NewReader(`{"service": "custom_field.list"}`)
req, err := http.NewRequestWithContext(ctx, "POST", "https://beebole-apps.com/api/v2", payload)
if err != nil {
continue
}
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 {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -6
View File
@@ -1,12 +1,12 @@
package besnappy
import (
b "bytes"
"context"
b64 "encoding/base64"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -15,30 +15,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"besnappy"}) + `\b([a-f0-9]{64})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("besnappy")}
// 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{"besnappy"}
}
// FromData will find and optionally verify Besnappy 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.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := b.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Besnappy,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
data := fmt.Sprintf("%s:x", resMatch)
@@ -54,6 +61,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+29 -22
View File
@@ -1,11 +1,11 @@
package besttime
import (
"bytes"
"context"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,54 +14,61 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"besttime"}) + `\b([0-9A-Za-z_]{36})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("besttime")}
// 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{"besttime"}
}
// FromData will find and optionally verify Besttime secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Besttime,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://besttime.app/api/v1/keys/"+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://besttime.app/api/v1/keys/"+resMatch, nil)
if err != nil {
continue
}
res, err := client.Do(req)
if err != nil {
continue
}
defer res.Body.Close()
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
if bytes.Contains(bodyBytes, []byte(`"status": "OK"`)) {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
if err == nil {
defer res.Body.Close()
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
body := string(bodyBytes)
if strings.Contains(body, `"status": "OK"`) {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
+18 -12
View File
@@ -1,11 +1,11 @@
package billomat
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,49 +20,55 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"billomat"}) + `\b([0-9a-z]{32})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"billomat"}) + `\b([0-9a-z]{1,})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("billomat")}
// 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{"billomat"}
}
// FromData will find and optionally verify Billomat secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resId := bytes.TrimSpace(idMatch[1])
resId := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Billomat,
Raw: resMatch,
RawV2: append(resMatch, resId...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resId),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://%s.billomat.net/api/v2/clients/myself", string(resId)), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://%s.billomat.net/api/v2/clients/myself", resId), nil)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("X-BillomatApiKey", string(resMatch))
req.Header.Add("X-BillomatApiKey", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+17 -7
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,34 +15,42 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"bitbar"}) + `\b([0-9a-z]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bitbar")}
// 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{"bitbar"}
}
// FromData will find and optionally verify Bitbar secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := match[1]
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Bitbar,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
data := []byte(fmt.Sprintf("%s:", resMatch))
baseToken := b64.StdEncoding.EncodeToString(data)
data := fmt.Sprintf("%s:", resMatch)
baseToken := b64.StdEncoding.EncodeToString([]byte(data))
req, err := http.NewRequestWithContext(ctx, "GET", "https://cloud.bitbar.com/api/me", nil)
if err != nil {
continue
@@ -54,6 +63,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -7
View File
@@ -1,10 +1,10 @@
package bitcoinaverage
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -19,38 +19,45 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"bitcoinaverage"}) + `\b([a-zA-Z0-9]{43})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bitcoinaverage")}
// 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{"bitcoinaverage"}
}
// FromData will find and optionally verify BitcoinAverage secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BitcoinAverage,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://apiv2.bitcoinaverage.com/websocket/get_ticket", nil)
if err != nil {
continue
}
req.Header.Add("x-ba-key", string(resMatch))
req.Header.Add("x-ba-key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+38 -19
View File
@@ -1,80 +1,99 @@
package bitfinex
import (
"bytes"
"context"
"flag"
"net/http"
"regexp"
"strings"
"github.com/bitfinexcom/bitfinex-api-go/v2/rest"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
"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{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
client = common.SaneHttpClient()
// related resource https://medium.com/@Bitfinex/api-development-update-april-65fe52f84124
apiKeyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"bitfinex"}) + `\b([A-Za-z0-9_-]{43})\b`)
apiSecretPat = regexp.MustCompile(detectors.PrefixRegex([]string{"bitfinex"}) + `\b([A-Za-z0-9_-]{43})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bitfinex")}
var (
api = flag.String("api", "https://api-pub.bitfinex.com/v2/", "v2 REST API URL")
)
// 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{"bitfinex"}
}
// FromData will find and optionally verify Bitfinex secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
apiKeyMatches := apiKeyPat.FindAllSubmatch(data, -1)
apiSecretMatches := apiSecretPat.FindAllSubmatch(data, -1)
dataStr := string(data)
apiKeyMatches := apiKeyPat.FindAllStringSubmatch(dataStr, -1)
apiSecretMatches := apiSecretPat.FindAllStringSubmatch(dataStr, -1)
for _, apiKeyMatch := range apiKeyMatches {
if len(apiKeyMatch) != 2 {
continue
}
apiKeyRes := bytes.TrimSpace(apiKeyMatch[1])
apiKeyRes := strings.TrimSpace(apiKeyMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Bitfinex,
Raw: apiKeyRes,
Raw: []byte(apiKeyRes),
}
for _, apiSecretMatch := range apiSecretMatches {
if len(apiSecretMatch) != 2 {
continue
}
apiSecretRes := bytes.TrimSpace(apiSecretMatch[1])
apiSecretRes := strings.TrimSpace(apiSecretMatch[1])
if bytes.Equal(apiKeyRes, apiSecretRes) {
if apiKeyRes == apiSecretRes {
continue
}
if verify {
key := string(apiKeyRes)
secret := string(apiSecretRes)
http.DefaultClient = client
c := rest.NewClient().Credentials(key, secret)
// thankfully official golang examples exist but you just need to dig their many repos https://github.com/bitfinexcom/bitfinex-api-go/blob/master/examples/v2/rest-orders/main.go
key := apiKeyRes
secret := apiSecretRes
http.DefaultClient = client // filed https://github.com/bitfinexcom/bitfinex-api-go/issues/238 to improve this
c := rest.NewClientWithURL(*api).Credentials(key, secret)
isValid := true
isValid := true // assume valid
_, err = c.Orders.AllHistory()
if err != nil {
if bytes.HasPrefix([]byte(err.Error()), []byte("POST https://")) {
if strings.HasPrefix(err.Error(), "POST https://") { // eg POST https://api-pub.bitfinex.com/v2/auth/r/orders/hist: 500 apikey: digest invalid (10100)
isValid = false
} else if detectors.IsKnownFalsePositive(apiKeyRes, detectors.DefaultFalsePositives, true) {
continue
} else {
if detectors.IsKnownFalsePositive(apiKeyRes, detectors.DefaultFalsePositives, true) {
continue
}
}
}
s1.Verified = isValid
// If there is a valid one, we need to stop iterating now and return the valid result
if isValid {
break
}
}
}
// By appending resutls in the outer loop we can reduce false positives if there are multiple
// combinations of secrets and IDs found.
if len(apiSecretMatches) > 0 {
results = append(results, s1)
}
@@ -1,11 +1,11 @@
package bitlyaccesstoken
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,30 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"bitly"}) + `\b([a-zA-Z-0-9]{40})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bitly")}
// 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{"bitly"}
}
// FromData will find and optionally verify BitLyAccessToken secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BitLyAccessToken,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -45,13 +52,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+21 -15
View File
@@ -1,7 +1,6 @@
package bitmex
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha256"
@@ -10,6 +9,7 @@ import (
"net/url"
"regexp"
"strconv"
"strings"
"time"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
@@ -19,40 +19,46 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"bitmex"}) + string([]byte{32, 13, 10}) + `[0-9a-zA-Z\-\_]{24}` + string([]byte{32, 13, 10}))
secretPat = regexp.MustCompile(detectors.PrefixRegex([]string{"bitmex"}) + string([]byte{32, 13, 10}) + `[0-9a-zA-Z\-\_]{48}` + string([]byte{32, 13, 10}))
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"bitmex"}) + `([ \r\n]{1}[0-9a-zA-Z\-\_]{24}[ \r\n]{1})`)
secretPat = regexp.MustCompile(detectors.PrefixRegex([]string{"bitmex"}) + `([ \r\n]{1}[0-9a-zA-Z\-\_]{48}[ \r\n]{1})`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bitmex")}
// 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{"bitmex"}
}
// FromData will find and optionally verify Bitmex 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.FindAllSubmatch(data, -1)
secretMatches := secretPat.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
secretMatches := secretPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, secretMatch := range secretMatches {
if len(secretMatch) != 2 {
continue
}
resSecretMatch := bytes.TrimSpace(secretMatch[1])
resSecretMatch := strings.TrimSpace(secretMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Bitmex,
Raw: resSecretMatch,
RawV2: append(resMatch, resSecretMatch...),
Raw: []byte(resSecretMatch),
RawV2: []byte(resMatch + resSecretMatch),
}
if verify {
@@ -62,15 +68,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
path := "/api/v1/user"
payload := url.Values{}
signature := getBitmexSignature(timestamp, string(resSecretMatch), action, path, payload.Encode())
req, err := http.NewRequestWithContext(ctx, action, "https://www.bitmex.com"+path, bytes.NewReader([]byte(payload.Encode())))
signature := getBitmexSignature(timestamp, resSecretMatch, action, path, payload.Encode())
req, err := http.NewRequestWithContext(ctx, action, "https://www.bitmex.com"+path, strings.NewReader(payload.Encode()))
if err != nil {
continue
}
req.Header.Add("api-expires", timestamp)
req.Header.Add("api-key", string(resMatch))
req.Header.Add("api-key", resMatch)
req.Header.Add("api-signature", signature)
res, err := client.Do(req)
if err == nil {
@@ -78,6 +83,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,11 +1,11 @@
package blablabus
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,30 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"blablabus"}) + `\b([0-9A-Za-z]{22})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("blablabus")}
// 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{"blablabus"}
}
// FromData will find and optionally verify Blablabus 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.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Blablabus,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -46,13 +53,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Token %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Token %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -7
View File
@@ -1,11 +1,11 @@
package blazemeter
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,25 +20,31 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"blazemeter", "runscope"}) + `\b([0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("blazemeter"), []byte("runscope")}
// 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{"blazemeter", "runscope"}
}
// FromData will find and optionally verify Blazemeter secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Blazemeter,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -47,13 +53,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,10 +1,10 @@
package blitapp
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,30 +13,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"blitapp"}) + `\b([a-zA-Z0-9_-]{39})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("blitapp")}
// 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{"blitapp"}
}
// FromData will find and optionally verify BlitApp secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BlitApp,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -44,13 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("API-Key", string(resMatch))
req.Header.Add("API-Key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+18 -9
View File
@@ -1,11 +1,11 @@
package blocknative
import (
"bytes"
"context"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,29 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"blocknative"}) + `\b([0-9Aa-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("blocknative")}
// 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{"blocknative"}
}
// FromData will find and optionally verify Blocknative secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BlockNative,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -44,8 +52,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", string(resMatch))
req.Header.Add("Authorization", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
@@ -53,9 +60,11 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
if !bytes.Contains(bodyBytes, []byte("valid")) {
body := string(bodyBytes)
if !strings.Contains(body, "valid") {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+15 -7
View File
@@ -1,10 +1,10 @@
package blogger
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,33 +13,40 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"blogger"}) + `\b([0-9A-Za-z-]{39})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("blogger")}
// 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{"blogger"}
}
// FromData will find and optionally verify Blogger secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Blogger,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://www.googleapis.com/blogger/v3/blogs/2399953?key="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://www.googleapis.com/blogger/v3/blogs/2399953?key="+resMatch, nil)
if err != nil {
continue
}
@@ -49,6 +56,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+16 -7
View File
@@ -1,10 +1,10 @@
package bombbomb
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,29 +13,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"bombbomb"}) + `\b([a-zA-Z0-9-._]{704})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bombbomb")}
// 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{"bombbomb"}
}
// FromData will find and optionally verify BombBomb secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BombBomb,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -43,13 +51,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", string(resMatch))
req.Header.Add("Authorization", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+16 -7
View File
@@ -1,11 +1,11 @@
package boostnote
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,29 +14,37 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"boostnote"}) + `\b([0-9a-f]{64})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("boostnote")}
// 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{"boostnote"}
}
// FromData will find and optionally verify BoostNote secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BoostNote,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -44,13 +52,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+23 -15
View File
@@ -1,12 +1,12 @@
package borgbase
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"time"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
@@ -16,50 +16,55 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"borgbase"}) + `\b([a-zA-Z0-9/_.-]{148,152})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("borgbase")}
// 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{"borgbase"}
}
// FromData will find and optionally verify Borgbase secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Borgbase,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
timeout := 10 * time.Second
client.Timeout = timeout
payload := bytes.NewBuffer([]byte(`{ "query": "{ sshList {id, name}}" }`))
payload := strings.NewReader(`{"query":"{ sshList {id, name}}"}`)
req, err := http.NewRequest("POST", "https://api.borgbase.com/graphql", payload)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
bodyBytes, err := io.ReadAll(res.Body)
if err == nil {
validResponse := bytes.Contains(bodyBytes, []byte(`"sshList":[]`))
bodyString := string(bodyBytes)
validResponse := strings.Contains(bodyString, `"sshList":[]`)
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
if validResponse {
@@ -67,8 +72,11 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
} else {
s1.Verified = false
}
} else if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
@@ -1,11 +1,11 @@
package braintreepayments
import (
"bytes"
"context"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,50 +14,57 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"braintree"}) + `\b([0-9a-f]{32})\b`)
idPat = regexp.MustCompile(detectors.PrefixRegex([]string{"braintree"}) + `\b([0-9a-z]{16})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("braintree")}
// 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{"braintree"}
}
// FromData will find and optionally verify BraintreePayments secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
idMatches := idPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
idMatches := idPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, idMatch := range idMatches {
if len(idMatch) != 2 {
continue
}
resIdMatch := bytes.TrimSpace(idMatch[1])
resIdMatch := strings.TrimSpace(idMatch[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BraintreePayments,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
payload := bytes.NewBufferString(`{"query": "query { ping }"}`)
payload := strings.NewReader(`{"query": "query { ping }"}`)
req, err := http.NewRequestWithContext(ctx, "POST", "https://payments.braintree-api.com/graphql", payload)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Braintree-Version", "2019-01-01")
req.SetBasicAuth(string(resIdMatch), string(resMatch))
req.SetBasicAuth(resIdMatch, resMatch)
res, err := client.Do(req)
if err == nil {
bodyBytes, err := io.ReadAll(res.Body)
@@ -65,12 +72,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
validResponse := bytes.Contains(bodyBytes, []byte(`"data":{`))
bodyString := string(bodyBytes)
validResponse := strings.Contains(bodyString, `"data":{`)
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 && validResponse {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+17 -9
View File
@@ -1,10 +1,10 @@
package brandfetch
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,48 +13,56 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"brandfetch"}) + `\b([0-9A-Za-z]{40})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("brandfetch")}
// 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{"brandfetch"}
}
// FromData will find and optionally verify Brandfetch secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Brandfetch,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
payload := bytes.NewReader([]byte(`{
payload := strings.NewReader(`{
"domain": "www.example.com"
}`))
}`)
req, err := http.NewRequestWithContext(ctx, "POST", "https://api.brandfetch.io/v1/color", payload)
if err != nil {
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("x-api-key", string(resMatch))
req.Header.Add("x-api-key", resMatch)
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+30 -23
View File
@@ -1,10 +1,10 @@
package browserstack
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -13,40 +13,46 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"https://", "http://", "hub-cloud.browserstack.com", "accessKey", "\"access_Key\":", "ACCESS_KEY", "key", "browserstackKey", "BS_AUTHKEY", "BROWSERSTACK_ACCESS_KEY"}) + `\b([0-9a-zA-Z]{20})\b`)
userPat = regexp.MustCompile(detectors.PrefixRegex([]string{"https://", "http://", "hub-cloud.browserstack.com", "userName", "\"username\":", "USER_NAME", "user", "browserstackUser", "BS_USERNAME", "BROWSERSTACK_USERNAME"}) + `\b([a-zA-Z\d]{3,18}[._-]+[a-zA-Z\d]{6})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("browserstack")}
// 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{"browserstack"}
}
// FromData will find and optionally verify BrowserStack secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
keyMatches := keyPat.FindAllSubmatch(data, -1)
userMatches := userPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
userMatches := userPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range keyMatches {
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
for _, userMatch := range userMatches {
if len(userMatch) != 2 {
continue
}
resUserMatch := bytes.TrimSpace(userMatch[1])
resUserMatch := strings.TrimSpace(userMatch[1])
result := detectors.Result{
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BrowserStack,
Raw: resMatch,
RawV2: append(resMatch, resUserMatch...),
Raw: []byte(resMatch),
RawV2: []byte(resMatch + resUserMatch),
}
if verify {
@@ -55,23 +61,24 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.SetBasicAuth(string(resUserMatch), string(resMatch))
req.SetBasicAuth(resUserMatch, resMatch)
res, err := client.Do(req)
if err != nil {
continue
}
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
result.Verified = true
} else if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
results = append(results, result)
results = append(results, s1)
}
}
return results, nil
}
+10 -7
View File
@@ -1,10 +1,10 @@
package browshot
import (
"bytes"
"context"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -25,27 +25,29 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("browshot")}
func (s Scanner) Keywords() []string {
return []string{"browshot"}
}
// FromData will find and optionally verify Browshot secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Browshot,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.browshot.com/api/v1/instance/list?key="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.browshot.com/api/v1/instance/list?key="+resMatch, nil)
if err != nil {
continue
}
@@ -55,6 +57,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+24 -20
View File
@@ -1,11 +1,11 @@
package bscscan
import (
"bytes"
"context"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -26,47 +26,51 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bscscan")}
func (s Scanner) Keywords() []string {
return []string{"bscscan"}
}
// FromData will find and optionally verify Bscscan 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.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BscScan,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.bscscan.com/api?module=account&action=balance&address=0x70F657164e5b75689b64B7fd1fA275F334f28e18&apikey="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.bscscan.com/api?module=account&action=balance&address=0x70F657164e5b75689b64B7fd1fA275F334f28e18&apikey="+resMatch, nil)
if err != nil {
continue
}
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
if !bytes.Contains(bodyBytes, []byte("NOTOK")) {
s1.Verified = true
} else {
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
body := string(bodyBytes)
if !strings.Contains(body, "NOTOK") {
s1.Verified = true
} else {
// This function will check false positives for common test words, but also it will make sur>
if detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
}
}
}
results = append(results, s1)
}
+13 -7
View File
@@ -1,11 +1,11 @@
package buddyns
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,26 +20,31 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"buddyns"}) + `\b([0-9a-z]{40})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("buddyns")}
// 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{"buddyns"}
}
// FromData will find and optionally verify Buddyns 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.FindAllSubmatch(data, -1)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_BuddyNS,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -48,13 +53,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("Token %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Token %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+17 -8
View File
@@ -1,12 +1,12 @@
package bugherd
import (
"bytes"
"context"
b64 "encoding/base64"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -15,34 +15,42 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"bugherd"}) + `\b([0-9a-z]{22})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bugherd")}
// 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{"bugherd"}
}
// FromData will find and optionally verify Bugherd secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Bugherd,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
data := append(resMatch, ':', 'x')
sEnc := b64.StdEncoding.EncodeToString(data)
data := fmt.Sprintf("%s:x", resMatch)
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
req, err := http.NewRequestWithContext(ctx, "GET", "https://www.bugherd.com/api_v2/projects.json", nil)
if err != nil {
continue
@@ -55,6 +63,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+14 -7
View File
@@ -1,11 +1,11 @@
package bugsnag
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -20,25 +20,31 @@ var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"bugsnag"}) + `\b([0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bugsnag")}
// 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{"bugsnag"}
}
// FromData will find and optionally verify Bugsnag secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Bugsnag,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -47,13 +53,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
continue
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", fmt.Sprintf("token %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("token %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+17 -9
View File
@@ -1,11 +1,11 @@
package buildkite
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -16,31 +16,38 @@ type Scanner struct{}
func (s Scanner) Version() int { return 1 }
// Make sure that the Scanner accomplishes the interface at compile time.
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var _ detectors.Versioner = (*Scanner)(nil)
var (
client = common.SaneHttpClient()
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"buildkite"}) + `\b([0-9a-z]{40})\b`)
// Make sure that your group is surrounded in boundary characters such as below to reduce false positives.
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"buildkite"}) + `\b([a-z0-9]{40})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("buildkite")}
// 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{"buildkite"}
}
// FromData will find and optionally verify Buildkite secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Buildkite,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -48,13 +55,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+10 -7
View File
@@ -1,11 +1,11 @@
package buildkitev2
import (
"bytes"
"context"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -29,23 +29,25 @@ var (
// Keywords are used for efficiently pre-filtering chunks.
// Use identifiers in the secret preferably, or the provider name.
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bkua_")}
func (s Scanner) Keywords() []string {
return []string{"bkua_"}
}
// FromData will find and optionally verify Buildkite secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Buildkite,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
@@ -53,13 +55,14 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
if err != nil {
continue
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", string(resMatch)))
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch))
res, err := client.Do(req)
if err == nil {
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
s1.Verified = true
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}
+26 -12
View File
@@ -1,11 +1,12 @@
package bulbul
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
@@ -14,51 +15,64 @@ import (
type Scanner struct{}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var (
client = 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{"bulbul"}) + `\b([a-z0-9]{32})\b`)
)
func (s Scanner) Keywords() [][]byte {
return [][]byte{[]byte("bulbul")}
// 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{"bulbul"}
}
// FromData will find and optionally verify Bulbul secrets in a given set of bytes.
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
matches := keyPat.FindAllSubmatch(data, -1)
dataStr := string(data)
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
for _, match := range matches {
if len(match) != 2 {
continue
}
resMatch := bytes.TrimSpace(match[1])
resMatch := strings.TrimSpace(match[1])
s1 := detectors.Result{
DetectorType: detectorspb.DetectorType_Bulbul,
Raw: resMatch,
Raw: []byte(resMatch),
}
if verify {
req, err := http.NewRequestWithContext(ctx, "GET", "https://prod-api.bulbul.io/view_all_users?api_key="+string(resMatch), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://prod-api.bulbul.io/view_all_users?api_key=%s", resMatch), nil)
if err != nil {
continue
}
res, err := client.Do(req)
if err == nil {
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
continue
}
bodyString := string(bodyBytes)
validResponse := strings.Contains(bodyString, `"message":"Successful",`)
defer res.Body.Close()
if res.StatusCode >= 200 && res.StatusCode < 300 {
responseBody, err := io.ReadAll(res.Body)
if err != nil {
continue
}
validResponse := bytes.Contains(responseBody, []byte(`"message":"Successful",`))
if validResponse {
s1.Verified = true
} else {
s1.Verified = false
}
} else {
// 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 detectors.IsKnownFalsePositive(resMatch, detectors.DefaultFalsePositives, true) {
continue
}

Some files were not shown because too many files have changed in this diff Show More