mirror of
https://github.com/trufflesecurity/trufflehog.git
synced 2024-11-10 07:04:24 +00:00
Introduce trufflehog:ignore
tag feature (#1433)
* init ignore * cleanup and add test * update readme
This commit is contained in:
parent
00920984e3
commit
18a70b64bb
3 changed files with 83 additions and 6 deletions
|
@ -151,6 +151,8 @@ trufflehog docker --image trufflesecurity/secrets --only-verified
|
|||
+ Unauthenticated GitHub scans have rate limits. To improve your rate limits, include the `--token` flag with a personal access token
|
||||
+ It says a private key was verified, what does that mean?
|
||||
+ Check out our Driftwood blog post to learn how to do this, in short we've confirmed the key can be used live for SSH or SSL [Blog post](https://trufflesecurity.com/blog/driftwood-know-if-private-keys-are-sensitive/)
|
||||
+ Is there an easy way to ignore specific secrets?
|
||||
+ If the scanned source [supports line numbers](https://github.com/trufflesecurity/trufflehog/blob/d6375ba92172fd830abb4247cca15e3176448c5d/pkg/engine/engine.go#L358-L365), then you can add a `trufflehog:ignore` comment on the line containing the secret to ignore that secrets.
|
||||
|
||||
|
||||
# :newspaper: What's new in v3?
|
||||
|
|
|
@ -53,6 +53,8 @@ func WithConcurrency(concurrency int) EngineOption {
|
|||
}
|
||||
}
|
||||
|
||||
const ignoreTag = "trufflehog:ignore"
|
||||
|
||||
func WithDetectors(verify bool, d ...detectors.Detector) EngineOption {
|
||||
return func(e *Engine) {
|
||||
if e.detectors == nil {
|
||||
|
@ -315,6 +317,7 @@ func (e *Engine) detectorWorker(ctx context.Context) {
|
|||
}
|
||||
for _, result := range results {
|
||||
resultChunk := chunk
|
||||
ignoreLinePresent := false
|
||||
if SupportsLineNumbers(chunk.SourceType) {
|
||||
copyChunk := *chunk
|
||||
copyMetaDataClone := proto.Clone(chunk.SourceMetadata)
|
||||
|
@ -322,9 +325,12 @@ func (e *Engine) detectorWorker(ctx context.Context) {
|
|||
copyChunk.SourceMetadata = copyMetaData
|
||||
}
|
||||
fragStart, mdLine := FragmentFirstLine(©Chunk)
|
||||
SetResultLineNumber(©Chunk, &result, fragStart, mdLine)
|
||||
ignoreLinePresent = SetResultLineNumber(©Chunk, &result, fragStart, mdLine)
|
||||
resultChunk = ©Chunk
|
||||
}
|
||||
if ignoreLinePresent {
|
||||
continue
|
||||
}
|
||||
result.DecoderType = decoderType
|
||||
e.results <- detectors.CopyMetadata(resultChunk, result)
|
||||
|
||||
|
@ -377,14 +383,18 @@ func SupportsLineNumbers(sourceType sourcespb.SourceType) bool {
|
|||
}
|
||||
|
||||
// FragmentLineOffset sets the line number for a provided source chunk with a given detector result.
|
||||
func FragmentLineOffset(chunk *sources.Chunk, result *detectors.Result) int64 {
|
||||
func FragmentLineOffset(chunk *sources.Chunk, result *detectors.Result) (int64, bool) {
|
||||
lines := bytes.Split(chunk.Data, []byte("\n"))
|
||||
for i, line := range lines {
|
||||
if bytes.Contains(line, result.Raw) {
|
||||
return int64(i)
|
||||
// if the line contains the ignore tag, we should ignore the result
|
||||
if bytes.Contains(line, []byte(ignoreTag)) {
|
||||
return int64(i), true
|
||||
}
|
||||
return int64(i), false
|
||||
}
|
||||
}
|
||||
return 0
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// FragmentFirstLine returns the first line number of a fragment along with a pointer to the value to update in the
|
||||
|
@ -411,7 +421,8 @@ func FragmentFirstLine(chunk *sources.Chunk) (int64, *int64) {
|
|||
}
|
||||
|
||||
// SetResultLineNumber sets the line number in the provided result.
|
||||
func SetResultLineNumber(chunk *sources.Chunk, result *detectors.Result, fragStart int64, mdLine *int64) {
|
||||
offset := FragmentLineOffset(chunk, result)
|
||||
func SetResultLineNumber(chunk *sources.Chunk, result *detectors.Result, fragStart int64, mdLine *int64) bool {
|
||||
offset, skip := FragmentLineOffset(chunk, result)
|
||||
*mdLine = fragStart + offset
|
||||
return skip
|
||||
}
|
||||
|
|
64
pkg/engine/engine_test.go
Normal file
64
pkg/engine/engine_test.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
||||
)
|
||||
|
||||
func TestFragmentLineOffset(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
chunk *sources.Chunk
|
||||
result *detectors.Result
|
||||
expectedLine int64
|
||||
ignore bool
|
||||
}{
|
||||
{
|
||||
name: "ignore found on same line",
|
||||
chunk: &sources.Chunk{
|
||||
Data: []byte("line1\nline2\nsecret here trufflehog:ignore\nline4"),
|
||||
},
|
||||
result: &detectors.Result{
|
||||
Raw: []byte("secret here"),
|
||||
},
|
||||
expectedLine: 2,
|
||||
ignore: true,
|
||||
},
|
||||
{
|
||||
name: "no ignore",
|
||||
chunk: &sources.Chunk{
|
||||
Data: []byte("line1\nline2\nsecret here\nline4"),
|
||||
},
|
||||
result: &detectors.Result{
|
||||
Raw: []byte("secret here"),
|
||||
},
|
||||
expectedLine: 2,
|
||||
ignore: false,
|
||||
},
|
||||
{
|
||||
name: "ignore on different line",
|
||||
chunk: &sources.Chunk{
|
||||
Data: []byte("line1\nline2\ntrufflehog:ignore\nline4\nsecret here\nline6"),
|
||||
},
|
||||
result: &detectors.Result{
|
||||
Raw: []byte("secret here"),
|
||||
},
|
||||
expectedLine: 4,
|
||||
ignore: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
lineOffset, isIgnored := FragmentLineOffset(tt.chunk, tt.result)
|
||||
if lineOffset != tt.expectedLine {
|
||||
t.Errorf("Expected line offset to be %d, got %d", tt.expectedLine, lineOffset)
|
||||
}
|
||||
if isIgnored != tt.ignore {
|
||||
t.Errorf("Expected isIgnored to be %v, got %v", tt.ignore, isIgnored)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue