-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose detector-specific false positive logic #2743
Changes from all commits
f18275a
9b61391
f117671
fbb5a49
8fcbddb
b161fe7
fa1d9d6
75de679
4997520
8c4bb82
bc8f998
7f9a380
6d67e91
16989c6
e3aba86
0975f0f
f907796
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ type Scanner struct { | |
|
||
// Ensure the Scanner satisfies the interface at compile time. | ||
var _ detectors.Detector = (*Scanner)(nil) | ||
var _ detectors.CustomFalsePositiveChecker = (*Scanner)(nil) | ||
|
||
var ( | ||
defaultClient = common.SaneHttpClient() | ||
|
@@ -94,6 +95,10 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result | |
return results, nil | ||
} | ||
|
||
func (s Scanner) IsFalsePositive(_ detectors.Result) bool { | ||
return false | ||
} | ||
Comment on lines
+98
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you consider creating a struct that implements this so it can be embedded into the // in detectors package
type SkipFalsePositiveCheck struct{}
func (SkipFalsePositiveCheck) IsFalsePositive(Result) bool {
return false
}
// elsewhere
type Scanner struct {
detectors.SkipFalsePositiveCheck
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, i didn't! does that save any implementation effort? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Marginally? imo it's a "nice-to-have" for a common scenario, especially for areas of the code that get a lot of outside contribution. |
||
|
||
func (s Scanner) Type() detectorspb.DetectorType { | ||
return detectorspb.DetectorType_AzureContainerRegistry | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,15 +8,17 @@ import ( | |
"unicode/utf8" | ||
|
||
ahocorasick "github.com/BobuSumisu/aho-corasick" | ||
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" | ||
|
||
"github.com/trufflesecurity/trufflehog/v3/pkg/context" | ||
) | ||
|
||
var DefaultFalsePositives = []FalsePositive{"example", "xxxxxx", "aaaaaa", "abcde", "00000", "sample", "www"} | ||
|
||
type FalsePositive string | ||
|
||
type CustomFalsePositiveChecker interface { | ||
IsFalsePositive(result Result) bool | ||
} | ||
|
||
//go:embed "badlist.txt" | ||
var badList []byte | ||
|
||
|
@@ -43,6 +45,17 @@ func init() { | |
filter = builder.Build() | ||
} | ||
|
||
func GetFalsePositiveCheck(detector Detector) func(Result) bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Neat! |
||
checker, ok := detector.(CustomFalsePositiveChecker) | ||
if ok { | ||
return checker.IsFalsePositive | ||
} | ||
|
||
return func(res Result) bool { | ||
return IsKnownFalsePositive(string(res.Raw), DefaultFalsePositives, true) | ||
} | ||
} | ||
|
||
// IsKnownFalsePositive will not return a valid secret finding if any of the disqualifying conditions are met | ||
// Currently that includes: No number, english word in key, or matches common example pattens. | ||
// Only the secret key material should be passed into this function | ||
|
@@ -132,34 +145,17 @@ func FilterResultsWithEntropy(ctx context.Context, results []Result, entropy flo | |
} | ||
|
||
// FilterKnownFalsePositives filters out known false positives from the results. | ||
func FilterKnownFalsePositives(ctx context.Context, results []Result, falsePositives []FalsePositive, wordCheck bool, shouldLog bool) []Result { | ||
func FilterKnownFalsePositives(ctx context.Context, detector Detector, results []Result, shouldLog bool) []Result { | ||
var filteredResults []Result | ||
|
||
isFalsePositive := GetFalsePositiveCheck(detector) | ||
|
||
for _, result := range results { | ||
if !result.Verified { | ||
switch result.DetectorType { | ||
case detectorspb.DetectorType_CustomRegex: | ||
filteredResults = append(filteredResults, result) | ||
case detectorspb.DetectorType_GCP, | ||
detectorspb.DetectorType_URI, | ||
detectorspb.DetectorType_AzureBatch, | ||
detectorspb.DetectorType_AzureContainerRegistry, | ||
detectorspb.DetectorType_Shopify, | ||
detectorspb.DetectorType_Postgres, | ||
detectorspb.DetectorType_MongoDB, | ||
detectorspb.DetectorType_JDBC: | ||
if !result.Verified && result.Raw != nil { | ||
if !isFalsePositive(result) { | ||
filteredResults = append(filteredResults, result) | ||
default: | ||
if result.Raw != nil { | ||
if !IsKnownFalsePositive(string(result.Raw), falsePositives, wordCheck) { | ||
filteredResults = append(filteredResults, result) | ||
} else { | ||
if shouldLog { | ||
ctx.Logger().Info("Filtered out known false positive", "result", result) | ||
} | ||
} | ||
} else { | ||
filteredResults = append(filteredResults, result) | ||
} | ||
} else if shouldLog { | ||
ctx.Logger().Info("Filtered out known false positive", "result", result) | ||
} | ||
} else { | ||
filteredResults = append(filteredResults, result) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: If all parameters are ignored, you can omit
_
. You can even omitc
in the pointer receiver.