Skip to content

Commit

Permalink
Feat/ignore finding (gitleaks#938)
Browse files Browse the repository at this point in the history
  • Loading branch information
zricethezav authored Aug 7, 2022
1 parent e890a8e commit 3bace4c
Show file tree
Hide file tree
Showing 11 changed files with 713 additions and 8 deletions.
651 changes: 651 additions & 0 deletions .gitleaksignore

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ stopwords = [
Refer to the default [gitleaks config](https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml) for examples or follow the [contributing guidelines](https://github.com/zricethezav/gitleaks/blob/master/README.md).

### Additional Configuration
#### gitleaks:allow
If you are knowingly committing a test secret that gitleaks will catch you can add a `gitleaks:allow` comment to that line which will instruct gitleaks
to ignore that secret. Ex:
```
Expand All @@ -367,6 +368,9 @@ class CustomClass:
```

#### .gitleaksignore
You can ignore specific findings by creating a `.gitleaksignore` file at the root of your repo. In release v8.10.0 Gitleaks added a `Fingerprint` value to the Gitleaks report. Each leak, or finding, has a Fingerprint that uniquely identifies a secret. Add this fingerprint to the `.gitleaksignore` file to ignore that specific secret. See Gitleaks' [.gitleaksignore](https://github.com/zricethezav/gitleaks/blob/master/.gitleaksignore) for an example.



## Secured by Jit
Expand Down
5 changes: 5 additions & 0 deletions cmd/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ func runDetect(cmd *cobra.Command, args []string) {
log.Fatal().Err(err)
}

// check for a .gitleaksignore file
if info, err := os.Stat(filepath.Join(source, ".gitleaksignore")); !os.IsNotExist(err) && !info.IsDir() {
detector.AddGitleaksIgnore(filepath.Join(source, ".gitleaksignore"))
}

// set exit code
exitCode, err := cmd.Flags().GetInt("exit-code")
if err != nil {
Expand Down
39 changes: 34 additions & 5 deletions detect/detect.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package detect

import (
"bufio"
"context"
"fmt"
"os"
Expand Down Expand Up @@ -64,6 +65,9 @@ type Detector struct {
// prefilter is a ahocorasick struct used for doing efficient string
// matching given a set of words (keywords from the rules in the config)
prefilter ahocorasick.AhoCorasick

// gitleaksIgnore
gitleaksIgnore map[string]bool
}

// Fragment contains the data to be scanned
Expand Down Expand Up @@ -96,11 +100,12 @@ func NewDetector(cfg config.Config) *Detector {
})

return &Detector{
commitMap: make(map[string]bool),
findingMutex: &sync.Mutex{},
findings: make([]report.Finding, 0),
Config: cfg,
prefilter: builder.Build(cfg.Keywords),
commitMap: make(map[string]bool),
gitleaksIgnore: make(map[string]bool),
findingMutex: &sync.Mutex{},
findings: make([]report.Finding, 0),
Config: cfg,
prefilter: builder.Build(cfg.Keywords),
}
}

Expand All @@ -123,6 +128,23 @@ func NewDetectorDefaultConfig() (*Detector, error) {
return NewDetector(cfg), nil
}

func (d *Detector) AddGitleaksIgnore(gitleaksIgnorePath string) error {
log.Debug().Msg("found .gitleaksignore file")
file, err := os.Open(gitleaksIgnorePath)

if err != nil {
return err
}

defer file.Close()
scanner := bufio.NewScanner(file)

for scanner.Scan() {
d.gitleaksIgnore[scanner.Text()] = true
}
return nil
}

// DetectBytes scans the given bytes and returns a list of findings
func (d *Detector) DetectBytes(content []byte) []report.Finding {
return d.DetectString(string(content))
Expand Down Expand Up @@ -428,6 +450,13 @@ func (d *Detector) Detect(fragment Fragment) []report.Finding {

// addFinding synchronously adds a finding to the findings slice
func (d *Detector) addFinding(finding report.Finding) {
// check if we should ignore this finding
if _, ok := d.gitleaksIgnore[finding.Fingerprint]; ok {
log.Debug().Msgf("ignoring finding with Fingerprint %s",
finding.Fingerprint)
return
}

d.findingMutex.Lock()
d.findings = append(d.findings, finding)
if d.Verbose {
Expand Down
3 changes: 3 additions & 0 deletions detect/detect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ func TestFromGit(t *testing.T) {
RuleID: "aws-access-key",
Tags: []string{"key", "AWS"},
Entropy: 3.0841837,
Fingerprint: "d0ce473c3c9f6934e8d274604cf9ceae63700f03",
},
{
Description: "AWS Access Key",
Expand All @@ -385,6 +386,7 @@ func TestFromGit(t *testing.T) {
RuleID: "aws-access-key",
Tags: []string{"key", "AWS"},
Entropy: 3.0841837,
Fingerprint: "df8d271fa20b928dfb12353cc16ddf9934225cb7",
},
},
},
Expand All @@ -410,6 +412,7 @@ func TestFromGit(t *testing.T) {
RuleID: "aws-access-key",
Tags: []string{"key", "AWS"},
Entropy: 3.0841837,
Fingerprint: "df8d271fa20b928dfb12353cc16ddf9934225cb7",
},
},
},
Expand Down
6 changes: 6 additions & 0 deletions detect/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package detect

import (
"crypto/sha1"
"encoding/json"
"fmt"
"math"
Expand All @@ -21,6 +22,11 @@ func augmentGitFinding(finding report.Finding, textFragment *gitdiff.TextFragmen
finding.EndLine += int(textFragment.NewPosition)
}

// generate finding hash
h := sha1.New()
h.Write([]byte(fmt.Sprintf("%s:%s:%s:%d", finding.Commit, finding.File, finding.RuleID, finding.StartLine)))
finding.Fingerprint = fmt.Sprintf("%x", h.Sum(nil))

if f.PatchHeader != nil {
finding.Commit = f.PatchHeader.SHA
finding.Message = f.PatchHeader.Message()
Expand Down
2 changes: 2 additions & 0 deletions report/csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func writeCsv(f []Finding, w io.WriteCloser) error {
"Message",
"Date",
"Email",
"Fingerprint",
})
if err != nil {
return err
Expand All @@ -44,6 +45,7 @@ func writeCsv(f []Finding, w io.WriteCloser) error {
f.Message,
f.Date,
f.Email,
f.Fingerprint,
})
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions report/csv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestWriteCSV(t *testing.T) {
Author: "John Doe",
Email: "johndoe@gmail.com",
Date: "10-19-2003",
Fingerprint: "fingerprint",
},
}},
{
Expand Down
3 changes: 3 additions & 0 deletions report/finding.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type Finding struct {

// Rule is the name of the rule that was matched
RuleID string

// unique identifer
Fingerprint string
}

// Redact removes sensitive information from a finding.
Expand Down
4 changes: 2 additions & 2 deletions testdata/expected/report/csv_simple.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
RuleID,Commit,File,Secret,Match,StartLine,EndLine,StartColumn,EndColumn,Author,Message,Date,Email
test-rule,0000000000000000,auth.py,a secret,line containing secret,1,2,1,2,John Doe,opps,10-19-2003,johndoe@gmail.com
RuleID,Commit,File,Secret,Match,StartLine,EndLine,StartColumn,EndColumn,Author,Message,Date,Email,Fingerprint
test-rule,0000000000000000,auth.py,a secret,line containing secret,1,2,1,2,John Doe,opps,10-19-2003,johndoe@gmail.com,fingerprint
3 changes: 2 additions & 1 deletion testdata/expected/report/json_simple.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"Date": "10-19-2003",
"Message": "opps",
"Tags": [],
"RuleID": "test-rule"
"RuleID": "test-rule",
"Fingerprint": ""
}
]

0 comments on commit 3bace4c

Please sign in to comment.