TruffleHog has a Blind SSRF in some Detectors
Description
TruffleHog is a secrets scanning tool. Prior to v3.81.9, this vulnerability allows a malicious actor to craft data in a way that, when scanned by specific detectors, could trigger the detector to make an unauthorized request to an endpoint chosen by the attacker. For an exploit to be effective, the target endpoint must be an unauthenticated GET endpoint that produces side effects. The victim must scan the maliciously crafted data and have such an endpoint targeted for the exploit to succeed. The vulnerability has been resolved in TruffleHog v3.81.9 and later versions.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/trufflesecurity/trufflehog/v3Go | < 3.81.9 | 3.81.9 |
Affected products
1- Range: < 3.81.9
Patches
1fe5624c70923Improve domain / url handling in detectors (#3221)
49 files changed · +385 −124
pkg/detectors/aha/aha.go+1 −2 modified@@ -8,7 +8,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -22,7 +21,7 @@ var ( // Ensure the Scanner satisfies the interface at compile time. _ detectors.Detector = (*Scanner)(nil) - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"aha"}) + `\b([0-9a-f]{64})\b`)
pkg/detectors/apiflash/apiflash.go+3 −3 modified@@ -3,11 +3,11 @@ package apiflash import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // 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`)
pkg/detectors/artifactory/artifactory.go+1 −2 modified@@ -8,7 +8,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -22,7 +21,7 @@ var ( // Ensure the Scanner satisfies the interface at compile time. _ detectors.Detector = (*Scanner)(nil) - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // 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}|\b[a-zA-Z0-9]{64})`)
pkg/detectors/auth0managementapitoken/auth0managementapitoken.go+1 −2 modified@@ -8,7 +8,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -22,7 +21,7 @@ var _ detectors.Detector = (*Scanner)(nil) var _ detectors.MaxSecretSizeProvider = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithLocalAddresses // 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
pkg/detectors/auth0oauth/auth0oauth.go+4 −4 modified@@ -2,13 +2,13 @@ package auth0oauth import ( "context" - regexp "github.com/wasilibs/go-re2" "io" "net/http" "net/url" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithLocalAddresses 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`) @@ -102,7 +102,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result if !strings.Contains(body, "access_denied") { s1.Verified = true - } + } } }
pkg/detectors/azurebatch/azurebatch.go+1 −2 modified@@ -12,7 +12,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -27,7 +26,7 @@ var _ detectors.Detector = (*Scanner)(nil) var _ detectors.CustomFalsePositiveChecker = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. urlPat = regexp.MustCompile(`https://(.{1,50})\.(.{1,50})\.batch\.azure\.com`) secretPat = regexp.MustCompile(`[A-Za-z0-9+/=]{88}`)
pkg/detectors/azurefunctionkey/azurefunctionkey.go+1 −2 modified@@ -8,7 +8,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -22,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"azure"}) + `\b([a-zA-Z0-9_-]{20,56})\b={0,2}`) azureUrlPat = regexp.MustCompile(`\bhttps:\/\/([a-zA-Z0-9-]{2,30})\.azurewebsites\.net\/api\/([a-zA-Z0-9-]{2,30})\b`)
pkg/detectors/azuresearchquerykey/azuresearchquerykey.go+1 −2 modified@@ -8,7 +8,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -22,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"azure"}) + `\b([0-9a-zA-Z]{52})\b`) urlPat = regexp.MustCompile(detectors.PrefixRegex([]string{"azure"}) + `https:\/\/([0-9a-z]{5,40})\.search\.windows\.net\/indexes\/([0-9a-z]{5,40})\b`)
pkg/detectors/azurestorage/azurestorage.go+1 −1 modified@@ -25,7 +25,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = http.DefaultClient + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses keyPat = regexp.MustCompile(`DefaultEndpointsProtocol=https;AccountName=(?P<account_name>[^;]+);AccountKey=(?P<account_key>[^;]+);EndpointSuffix=core\.windows\.net`) )
pkg/detectors/caspio/caspio.go+3 −3 modified@@ -3,11 +3,11 @@ package caspio import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"caspio"}) + `\b([a-z0-9]{50})\b`)
pkg/detectors/databrickstoken/databrickstoken.go+3 −3 modified@@ -3,11 +3,11 @@ package databrickstoken import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. domain = regexp.MustCompile(`\b([a-z0-9-]+(?:\.[a-z0-9-]+)*\.(cloud\.databricks\.com|gcp\.databricks\.com|azurewebsites\.net))\b`)
pkg/detectors/deputy/deputy.go+3 −3 modified@@ -3,11 +3,11 @@ package deputy import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"deputy"}) + `\b([0-9a-z]{32})\b`)
pkg/detectors/detectors.go+10 −0 modified@@ -241,3 +241,13 @@ func RedactURL(u url.URL) string { u.User = url.UserPassword(u.User.Username(), "********") return strings.TrimSpace(strings.Replace(u.String(), "%2A", "*", -1)) } + +func ParseURLAndStripPathAndParams(u string) (*url.URL, error) { + parsedURL, err := url.Parse(u) + if err != nil { + return nil, err + } + parsedURL.Path = "" + parsedURL.RawQuery = "" + return parsedURL, nil +}
pkg/detectors/discordwebhook/discordwebhook.go+1 −2 modified@@ -7,7 +7,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -18,7 +17,7 @@ type Scanner struct{} var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(`(https:\/\/discord\.com\/api\/webhooks\/[0-9]{18}\/[0-9a-zA-Z-]{68})`)
pkg/detectors/fibery/fibery.go+3 −3 modified@@ -3,12 +3,12 @@ package fibery import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" "time" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"fibery"}) + `\b([0-9a-f]{8}.[0-9a-f]{35})\b`)
pkg/detectors/freshbooks/freshbooks.go+4 −4 modified@@ -3,12 +3,12 @@ package freshbooks import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "io" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,10 +21,10 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() - + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"freshbooks"}) + `\b([0-9a-z]{64})\b`) + // TODO: this domain pattern is too restrictive uriPat = regexp.MustCompile(detectors.PrefixRegex([]string{"freshbooks"}) + `\b(https://www.[0-9A-Za-z_-]{1,}.com)\b`) )
pkg/detectors/grafanaserviceaccount/grafanaserviceaccount.go+3 −3 modified@@ -3,11 +3,11 @@ package grafanaserviceaccount import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(`\b(glsa_[0-9a-zA-Z_]{41})\b`) domainPat = regexp.MustCompile(`\b([a-zA-Z0-9-]+\.grafana\.net)\b`)
pkg/detectors/http.go+154 −0 added@@ -0,0 +1,154 @@ +package detectors + +import ( + "context" + "errors" + "net" + "net/http" + "time" +) + +var DetectorHttpClientWithNoLocalAddresses *http.Client +var DetectorHttpClientWithLocalAddresses *http.Client + +const DefaultResponseTimeout = 5 * time.Second +const DefaultUserAgent = "TruffleHog" + +func init() { + DetectorHttpClientWithLocalAddresses = NewDetectorHttpClient( + WithTransport(NewDetectorTransport(DefaultUserAgent, nil)), + WithTimeout(DefaultResponseTimeout), + WithNoFollowRedirects(), + ) + DetectorHttpClientWithNoLocalAddresses = NewDetectorHttpClient( + WithTransport(NewDetectorTransport(DefaultUserAgent, nil)), + WithTimeout(DefaultResponseTimeout), + WithNoFollowRedirects(), + WithNoLocalIP(), + ) +} + +// ClientOption defines a function type that modifies an http.Client. +type ClientOption func(*http.Client) + +// WithNoFollowRedirects allows disabling automatic following of redirects. +func WithNoFollowRedirects() ClientOption { + return func(c *http.Client) { + c.CheckRedirect = func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + } + } +} + +type detectorTransport struct { + T http.RoundTripper + userAgent string +} + +func (t *detectorTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Add("User-Agent", t.userAgent) + return t.T.RoundTrip(req) +} + +var defaultDialer = &net.Dialer{ + Timeout: 2 * time.Second, + KeepAlive: 5 * time.Second, +} + +func NewDetectorTransport(userAgent string, T http.RoundTripper) http.RoundTripper { + if T == nil { + T = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: defaultDialer.DialContext, + MaxIdleConns: 100, + MaxIdleConnsPerHost: 5, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 3 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } + } + return &detectorTransport{T: T, userAgent: userAgent} +} + +func isLocalIP(ip net.IP) bool { + if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsPrivate() { + return true + } + + return false +} + +var ErrNoLocalIP = errors.New("dialing local IP addresses is not allowed") + +func WithNoLocalIP() ClientOption { + return func(c *http.Client) { + if c.Transport == nil { + c.Transport = &http.Transport{} + } + + // Type assertion to get the underlying *http.Transport + transport, ok := c.Transport.(*http.Transport) + if !ok { + // If c.Transport is not *http.Transport, check if it is wrapped in a detectorTransport + dt, ok := c.Transport.(*detectorTransport) + if !ok { + panic("unsupported transport type") + } + transport, ok = dt.T.(*http.Transport) + if !ok { + panic("underlying transport is not *http.Transport") + } + } + + // If the original DialContext is nil, set it to the default dialer + if transport.DialContext == nil { + transport.DialContext = defaultDialer.DialContext + } + originalDialContext := transport.DialContext + transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + host, port, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + ips, err := net.LookupIP(host) + if err != nil { + return nil, err + } + + for _, ip := range ips { + if isLocalIP(ip) { + return nil, ErrNoLocalIP + } + } + + return originalDialContext(ctx, network, net.JoinHostPort(host, port)) + } + } +} + +// WithTransport sets a custom transport for the http.Client. +func WithTransport(transport http.RoundTripper) ClientOption { + return func(c *http.Client) { + c.Transport = transport + } +} + +// WithTimeout sets a timeout for the http.Client. +func WithTimeout(timeout time.Duration) ClientOption { + return func(c *http.Client) { + c.Timeout = timeout + } +} + +func NewDetectorHttpClient(opts ...ClientOption) *http.Client { + httpClient := &http.Client{ + Transport: NewDetectorTransport(DefaultUserAgent, nil), + Timeout: DefaultResponseTimeout, + } + + for _, opt := range opts { + opt(httpClient) + } + return httpClient +}
pkg/detectors/http_test.go+94 −0 added@@ -0,0 +1,94 @@ +package detectors + +import ( + "context" + "net" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestWithNoLocalIP(t *testing.T) { + t.Run("Prevents dialing local IP", func(t *testing.T) { + client := &http.Client{} + WithNoLocalIP()(client) + + transport, ok := client.Transport.(*http.Transport) + assert.True(t, ok, "Expected transport to be *http.Transport") + + _, err := transport.DialContext(context.Background(), "tcp", "127.0.0.1:8080") + assert.Error(t, err) + assert.ErrorIs(t, err, ErrNoLocalIP) + }) + + t.Run("Allows dialing non-local host", func(t *testing.T) { + client := &http.Client{} + WithNoLocalIP()(client) + + transport, ok := client.Transport.(*http.Transport) + assert.True(t, ok, "Expected transport to be *http.Transport") + + conn, err := transport.DialContext(context.Background(), "tcp", "google.com:80") + assert.NoError(t, err) + assert.NotNil(t, conn) + conn.Close() + }) + + t.Run("Allows dialing non-local IP", func(t *testing.T) { + client := &http.Client{} + WithNoLocalIP()(client) + + transport, ok := client.Transport.(*http.Transport) + assert.True(t, ok, "Expected transport to be *http.Transport") + + conn, err := transport.DialContext(context.Background(), "tcp", "1.1.1.1:80") + assert.NoError(t, err) + assert.NotNil(t, conn) + conn.Close() + }) + + t.Run("Handles invalid address", func(t *testing.T) { + client := &http.Client{} + WithNoLocalIP()(client) + + transport, ok := client.Transport.(*http.Transport) + assert.True(t, ok, "Expected transport to be *http.Transport") + + _, err := transport.DialContext(context.Background(), "tcp", "invalid-address") + assert.Error(t, err) + }) + + t.Run("Handles non-existent hostname", func(t *testing.T) { + client := &http.Client{} + WithNoLocalIP()(client) + + transport, ok := client.Transport.(*http.Transport) + assert.True(t, ok, "Expected transport to be *http.Transport") + + _, err := transport.DialContext(context.Background(), "tcp", "non-existent-host.local:80") + assert.Error(t, err) + }) +} + +func TestIsLocalIP(t *testing.T) { + testCases := []struct { + name string + ip net.IP + expected bool + }{ + {"Loopback IPv4", net.ParseIP("127.0.0.1"), true}, + {"Loopback IPv6", net.ParseIP("::1"), true}, + {"Private IPv4", net.ParseIP("192.168.1.1"), true}, + {"Private IPv6", net.ParseIP("fd00::1"), true}, + {"Public IPv4", net.ParseIP("8.8.8.8"), false}, + {"Public IPv6", net.ParseIP("2001:4860:4860::8888"), false}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := isLocalIP(tc.ip) + assert.Equal(t, tc.expected, result) + }) + } +}
pkg/detectors/invoiceocean/invoiceocean.go+3 −3 modified@@ -3,11 +3,11 @@ package invoiceocean import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"invoiceocean"}) + `\b([0-9A-Za-z]{20})\b`)
pkg/detectors/jiratoken/v1/jiratoken.go+1 −2 modified@@ -9,7 +9,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -26,7 +25,7 @@ var _ detectors.Versioner = (*Scanner)(nil) func (Scanner) Version() int { return 1 } var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. tokenPat = regexp.MustCompile(detectors.PrefixRegex([]string{"jira"}) + `\b([a-zA-Z-0-9]{24})\b`)
pkg/detectors/jiratoken/v2/jiratoken_v2.go+1 −2 modified@@ -9,7 +9,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -26,7 +25,7 @@ var _ detectors.Versioner = (*Scanner)(nil) func (Scanner) Version() int { return 2 } var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithLocalAddresses // https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/ // Tokens created after Jan 18 2023 use a variable length
pkg/detectors/kanban/kanban.go+3 −3 modified@@ -3,11 +3,11 @@ package kanban import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"kanban"}) + `\b([0-9A-Z]{12})\b`)
pkg/detectors/kanbantool/kanbantool.go+3 −3 modified@@ -3,11 +3,11 @@ package kanbantool import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"kanbantool"}) + `\b([0-9A-Z]{12})\b`)
pkg/detectors/liveagent/liveagent.go+3 −3 modified@@ -3,11 +3,11 @@ package liveagent import ( "context" "encoding/json" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. domainPat = regexp.MustCompile(`\b(https?://[A-Za-z0-9-]+\.ladesk\.com)\b`)
pkg/detectors/loggly/loggly.go+3 −3 modified@@ -3,11 +3,11 @@ package loggly import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. domainPat = regexp.MustCompile(`\b([a-zA-Z0-9-]+\.loggly\.com)\b`) keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"loggly"}) + `\b([a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12})\b`)
pkg/detectors/metabase/metabase.go+11 −4 modified@@ -3,12 +3,12 @@ package metabase import ( "context" "encoding/json" - regexp "github.com/wasilibs/go-re2" "io" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"metabase"}) + `\b([a-zA-Z0-9-]{36})\b`) @@ -54,14 +54,21 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result } resURLMatch := strings.TrimSpace(urlMatch[1]) + u, err := detectors.ParseURLAndStripPathAndParams(resURLMatch) + if err != nil { + // if the URL is invalid just move onto the next one + continue + } + s1 := detectors.Result{ DetectorType: detectorspb.DetectorType_Metabase, Raw: []byte(resMatch), RawV2: []byte(resMatch + resURLMatch), } if verify { - req, err := http.NewRequestWithContext(ctx, http.MethodGet, resURLMatch+"/api/user/current", nil) + u.Path = "/api/user/current" + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { continue }
pkg/detectors/microsoftteamswebhook/microsoftteamswebhook.go+1 −3 modified@@ -6,11 +6,9 @@ import ( "io" "net/http" "strings" - "time" regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -24,7 +22,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClientTimeOut(5 * time.Second) + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(`(https:\/\/[a-zA-Z-0-9]+\.webhook\.office\.com\/webhookb2\/[a-zA-Z-0-9]{8}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{12}\@[a-zA-Z-0-9]{8}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{12}\/IncomingWebhook\/[a-zA-Z-0-9]{32}\/[a-zA-Z-0-9]{8}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{4}-[a-zA-Z-0-9]{12})`)
pkg/detectors/mite/mite.go+3 −3 modified@@ -3,11 +3,11 @@ package mite import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"mite"}) + `\b([0-9a-z]{16})\b`)
pkg/detectors/okta/okta.go+1 −2 modified@@ -9,7 +9,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -64,7 +63,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", fmt.Sprintf("SSWS %s", token)) - resp, err := common.SaneHttpClient().Do(req) + resp, err := detectors.DetectorHttpClientWithNoLocalAddresses.Do(req) if err != nil { continue }
pkg/detectors/openvpn/openvpn.go+1 −2 modified@@ -9,7 +9,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -23,7 +22,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses clientIDPat = regexp.MustCompile(detectors.PrefixRegex([]string{"openvpn"}) + `\b([A-Za-z0-9-]{3,40}\.[A-Za-z0-9-]{3,40})\b`) clientSecretPat = regexp.MustCompile(`\b([a-zA-Z0-9_-]{64,})\b`)
pkg/detectors/planviewleankit/planviewleankit.go+3 −3 modified@@ -3,11 +3,11 @@ package planviewleankit import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"planviewleankit", "planview"}) + `\b([0-9a-f]{128})\b`)
pkg/detectors/portainer/portainer.go+11 −6 modified@@ -3,11 +3,11 @@ package portainer import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. endpointPat = regexp.MustCompile(detectors.PrefixRegex([]string{"portainer"}) + `\b(https?:\/\/\S+(:[0-9]{4,5})?)\b`) tokenPat = regexp.MustCompile(detectors.PrefixRegex([]string{"portainer"}) + `\b(eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\.[0-9A-Za-z]{50,310}\.[0-9A-Z-a-z\-_]{43})\b`) @@ -49,6 +49,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result for _, endpointMatch := range endpointMatches { resEndpointMatch := strings.TrimSpace(endpointMatch[1]) + u, err := detectors.ParseURLAndStripPathAndParams(resEndpointMatch) + if err != nil { + // if the URL is invalid just move onto the next one + continue + } + u.Path = "/api/endpoints" + s1 := detectors.Result{ DetectorType: detectorspb.DetectorType_Portainer, Raw: []byte(resMatch), @@ -60,7 +67,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result if client == nil { client = defaultClient } - req, err := http.NewRequestWithContext(ctx, "GET", resEndpointMatch+"/api/endpoints", nil) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { continue } @@ -81,8 +88,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result } } - - if len(endpointMatches) > 0 { results = append(results, s1) }
pkg/detectors/portainertoken/portainertoken.go+11 −4 modified@@ -3,11 +3,11 @@ package portainertoken import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"portainertoken"}) + `\b(ptr_[A-Za-z0-9\/_\-+=]{20,60})`) endpointPat = regexp.MustCompile(detectors.PrefixRegex([]string{"portainer"}) + `\b(https?:\/\/\S+(:[0-9]{4,5})?)\b`) @@ -49,6 +49,13 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result for _, endpointMatch := range endpointMatches { resEndpointMatch := strings.TrimSpace(endpointMatch[1]) + u, err := detectors.ParseURLAndStripPathAndParams(resEndpointMatch) + if err != nil { + // if the URL is invalid just move onto the next one + continue + } + u.Path = "/api/stacks" + s1 := detectors.Result{ DetectorType: detectorspb.DetectorType_PortainerToken, Raw: []byte(resMatch), @@ -60,7 +67,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result if client == nil { client = defaultClient } - req, err := http.NewRequestWithContext(ctx, "GET", resEndpointMatch+"/api/stacks", nil) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { continue }
pkg/detectors/repairshopr/repairshopr.go+3 −3 modified@@ -3,11 +3,11 @@ package repairshopr import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"repairshopr"}) + `\b([a-zA-Z0-9-]{51})\b`)
pkg/detectors/ringcentral/ringcentral.go+3 −1 modified@@ -3,10 +3,11 @@ package ringcentral import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" @@ -24,6 +25,7 @@ var ( // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"ringcentral"}) + `\b([0-9A-Za-z_-]{22})\b`) + // TODO: this domain pattern is too restrictive uriPat = regexp.MustCompile(detectors.PrefixRegex([]string{"ringcentral"}) + `\b(https://www.[0-9A-Za-z_-]{1,}.com)\b`) )
pkg/detectors/salesforce/salesforce.go+3 −2 modified@@ -3,10 +3,11 @@ package salesforce import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" @@ -25,7 +26,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. accessTokenPat = regexp.MustCompile(`\b00[a-zA-Z0-9]{13}![a-zA-Z0-9_.]{96}\b`) instancePat = regexp.MustCompile(`\bhttps://[0-9a-zA-Z-\.]{1,100}\.my\.salesforce\.com\b`)
pkg/detectors/salesmate/salesmate.go+3 −3 modified@@ -3,11 +3,11 @@ package salesmate import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -20,7 +20,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"salesmate"}) + `\b([0-9Aa-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b`)
pkg/detectors/shopify/shopify.go+1 −2 modified@@ -8,7 +8,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -22,7 +21,7 @@ var _ detectors.Detector = (*Scanner)(nil) var _ detectors.CustomFalsePositiveChecker = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(`\b(shppa_|shpat_)([0-9A-Fa-f]{32})\b`)
pkg/detectors/signalwire/signalwire.go+3 −3 modified@@ -4,11 +4,11 @@ import ( "context" b64 "encoding/base64" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"signalwire"}) + `\b([0-9A-Za-z]{50})\b`)
pkg/detectors/signalwire/signalwire_test.go+1 −1 modified@@ -23,7 +23,7 @@ func TestSignalwire_FromChunk(t *testing.T) { if err != nil { t.Fatalf("could not get test secrets from GCP: %s", err) } - id := testSecrets.MustGetField("SGINALWIRE_ID") + id := testSecrets.MustGetField("SIGNALWIRE_ID") secret := testSecrets.MustGetField("SIGNALWIRE_TOKEN") url := testSecrets.MustGetField("SIGNALWIRE_URL") inactiveSecret := testSecrets.MustGetField("SIGNALWIRE_INACTIVE")
pkg/detectors/slackwebhook/slackwebhook.go+1 −2 modified@@ -8,7 +8,6 @@ import ( "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" regexp "github.com/wasilibs/go-re2" @@ -23,7 +22,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPats = map[string]*regexp.Regexp{ "Slack Service Web Hook": regexp.MustCompile(`(https://hooks\.slack\.com/services/T[A-Z0-9]+/B[A-Z0-9]+/[A-Za-z0-9]{23,25})`),
pkg/detectors/sugester/sugester.go+3 −3 modified@@ -2,11 +2,11 @@ package sugester import ( "context" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -19,7 +19,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"sugester"}) + `\b([a-zA-Z0-9]{32})\b`)
pkg/detectors/thinkific/thinkific.go+3 −3 modified@@ -3,12 +3,12 @@ package thinkific import ( "context" "fmt" - regexp "github.com/wasilibs/go-re2" "io" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"thinkific"}) + `\b([0-9a-f]{32})\b`)
pkg/detectors/tineswebhook/tineswebhook.go+1 −5 modified@@ -7,7 +7,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -18,7 +17,7 @@ type Scanner struct{} var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(`(https://[\w-]+\.tines\.com/webhook/[a-z0-9]{32}/[a-z0-9]{32})`) @@ -56,9 +55,6 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result res, err := client.Do(req) if err == nil { defer res.Body.Close() - if err != nil { - continue - } if res.StatusCode >= 200 && res.StatusCode < 300 { s1.Verified = true }
pkg/detectors/uri/uri.go+2 −2 modified@@ -9,7 +9,6 @@ import ( regexp "github.com/wasilibs/go-re2" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -26,7 +25,8 @@ var _ detectors.CustomFalsePositiveChecker = (*Scanner)(nil) var ( keyPat = regexp.MustCompile(`\b(?:https?:)?\/\/[\S]{3,50}:([\S]{3,50})@[-.%\w\/:]+\b`) - defaultClient = common.SaneHttpClient() + // TODO: make local addr opt-out + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses ) // Keywords are used for efficiently pre-filtering chunks.
pkg/detectors/zapierwebhook/zapierwebhook.go+3 −3 modified@@ -2,11 +2,11 @@ package zapierwebhook import ( "context" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -17,7 +17,7 @@ type Scanner struct{} var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(`(https:\/\/hooks\.zapier\.com\/hooks\/catch\/[A-Za-z0-9\/]{16})`)
pkg/detectors/zendeskapi/zendeskapi.go+3 −3 modified@@ -4,11 +4,11 @@ import ( "context" b64 "encoding/base64" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" "strings" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" ) @@ -21,7 +21,7 @@ type Scanner struct{ var _ detectors.Detector = (*Scanner)(nil) var ( - client = common.SaneHttpClient() + client = detectors.DetectorHttpClientWithNoLocalAddresses token = regexp.MustCompile(detectors.PrefixRegex([]string{"zendesk"}) + `([A-Za-z0-9_-]{40})`) email = regexp.MustCompile(`\b([a-zA-Z-0-9-]{5,16}\@[a-zA-Z-0-9]{4,16}\.[a-zA-Z-0-9]{3,6})\b`)
pkg/detectors/zulipchat/zulipchat.go+1 −1 modified@@ -23,7 +23,7 @@ type Scanner struct { var _ detectors.Detector = (*Scanner)(nil) var ( - defaultClient = common.SaneHttpClient() + defaultClient = detectors.DetectorHttpClientWithNoLocalAddresses // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. keyPat = regexp.MustCompile(common.BuildRegex(common.AlphaNumPattern, "", 32))
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-3r74-v83p-f4f4ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-43379ghsaADVISORY
- github.com/trufflesecurity/trufflehog/commit/fe5624c70923355128868cffd647b6e2cfe11443ghsax_refsource_MISCWEB
- github.com/trufflesecurity/trufflehog/security/advisories/GHSA-3r74-v83p-f4f4ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.