Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 249 additions & 0 deletions .2ms.yml

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions engine/detect/baseline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package detect

import (
"encoding/json"
"fmt"
"os"
"path/filepath"

"github.com/zricethezav/gitleaks/v8/report"
)

// IsNew returns true if the finding is not present in the baseline slice.
func IsNew(finding *report.Finding, baseline []report.Finding) bool {
for i := range baseline {
if findingsEqualExceptFingerprint(finding, &baseline[i]) {
return false
}
}
return true
}

// findingsEqualExceptFingerprint compares all fields except Fingerprint.
func findingsEqualExceptFingerprint(a, b *report.Finding) bool {
return a.Author == b.Author &&
a.Commit == b.Commit &&
a.Date == b.Date &&
a.Description == b.Description &&
a.Email == b.Email &&
a.EndColumn == b.EndColumn &&
a.EndLine == b.EndLine &&
a.Entropy == b.Entropy &&
a.File == b.File &&
// Omit checking Fingerprint - if the format of the fingerprint changes, the users will see unexpected behavior
a.Match == b.Match &&
a.Message == b.Message &&
a.RuleID == b.RuleID &&
a.Secret == b.Secret &&
a.StartColumn == b.StartColumn &&
a.StartLine == b.StartLine
}

func LoadBaseline(baselinePath string) ([]report.Finding, error) {
bytes, err := os.ReadFile(baselinePath)
if err != nil {
return nil, fmt.Errorf("could not open %s", baselinePath)
}

var previousFindings []report.Finding
err = json.Unmarshal(bytes, &previousFindings)
if err != nil {
return nil, fmt.Errorf("the format of the file %s is not supported", baselinePath)
}

return previousFindings, nil
}

func (d *Detector) AddBaseline(baselinePath, source string) error {
if baselinePath != "" {
absoluteSource, err := filepath.Abs(source)
if err != nil {
return err
}

absoluteBaseline, err := filepath.Abs(baselinePath)
if err != nil {
return err
}

relativeBaseline, err := filepath.Rel(absoluteSource, absoluteBaseline)
if err != nil {
return err
}

baseline, err := LoadBaseline(baselinePath)
if err != nil {
return err
}

d.baseline = baseline
baselinePath = relativeBaseline
}

d.baselinePath = baselinePath
return nil
}
88 changes: 88 additions & 0 deletions engine/detect/baseline_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package detect

import (
"errors"
"testing"

"github.com/stretchr/testify/assert"

"github.com/zricethezav/gitleaks/v8/report"
)

func TestIsNew(t *testing.T) {
tests := []struct {
findings report.Finding
baseline []report.Finding
expect bool
}{
{
findings: report.Finding{
Author: "a",
Commit: "0000",
},
baseline: []report.Finding{
{
Author: "a",
Commit: "0000",
},
},
expect: false,
},
{
findings: report.Finding{
Author: "a",
Commit: "0000",
},
baseline: []report.Finding{
{
Author: "a",
Commit: "0002",
},
},
expect: true,
},
{
findings: report.Finding{
Author: "a",
Commit: "0000",
Tags: []string{"a", "b"},
},
baseline: []report.Finding{
{
Author: "a",
Commit: "0000",
Tags: []string{"a", "c"},
},
},
expect: false, // Updated tags doesn't make it a new finding
},
}
for _, test := range tests {
assert.Equal(t, test.expect, IsNew(&test.findings, test.baseline))
}
}

func TestFileLoadBaseline(t *testing.T) {
tests := []struct {
Filename string
ExpectedError error
}{
{
Filename: "../../tests/testData/baseline/baseline.csv",
ExpectedError: errors.New("the format of the file ../../tests/testData/baseline/baseline.csv is not supported"),
},
{
Filename: "../../tests/testData/baseline/baseline.sarif",
ExpectedError: errors.New("the format of the file ../../tests/testData/baseline/baseline.sarif is not supported"),
},
{
Filename: "../../tests/testData/baseline/notfound.json",
ExpectedError: errors.New("could not open ../../tests/testData/baseline/notfound.json"),
},
}

for _, test := range tests {
_, err := LoadBaseline(test.Filename)
assert.Equal(t, test.ExpectedError, err)
}
}
Loading
Loading