allowlist.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package config
  2. import (
  3. "errors"
  4. "strings"
  5. "golang.org/x/exp/maps"
  6. "github.com/zricethezav/gitleaks/v8/regexp"
  7. )
  8. type AllowlistMatchCondition int
  9. const (
  10. AllowlistMatchOr AllowlistMatchCondition = iota
  11. AllowlistMatchAnd
  12. )
  13. func (a AllowlistMatchCondition) String() string {
  14. return [...]string{
  15. "OR",
  16. "AND",
  17. }[a]
  18. }
  19. // Allowlist allows a rule to be ignored for specific
  20. // regexes, paths, and/or commits
  21. type Allowlist struct {
  22. // Short human readable description of the allowlist.
  23. Description string
  24. // MatchCondition determines whether all criteria must match.
  25. MatchCondition AllowlistMatchCondition
  26. // Commits is a slice of commit SHAs that are allowed to be ignored. Defaults to "OR".
  27. Commits []string
  28. // Paths is a slice of path regular expressions that are allowed to be ignored.
  29. Paths []*regexp.Regexp
  30. // Can be `match` or `line`.
  31. //
  32. // If `match` the _Regexes_ will be tested against the match of the _Rule.Regex_.
  33. //
  34. // If `line` the _Regexes_ will be tested against the entire line.
  35. //
  36. // If RegexTarget is empty, it will be tested against the found secret.
  37. RegexTarget string
  38. // Regexes is slice of content regular expressions that are allowed to be ignored.
  39. Regexes []*regexp.Regexp
  40. // StopWords is a slice of stop words that are allowed to be ignored.
  41. // This targets the _secret_, not the content of the regex match like the
  42. // Regexes slice.
  43. StopWords []string
  44. // validated is an internal flag to track whether `Validate()` has been called.
  45. validated bool
  46. }
  47. func (a *Allowlist) Validate() error {
  48. if a.validated {
  49. return nil
  50. }
  51. // Disallow empty allowlists.
  52. if len(a.Commits) == 0 &&
  53. len(a.Paths) == 0 &&
  54. len(a.Regexes) == 0 &&
  55. len(a.StopWords) == 0 {
  56. return errors.New("must contain at least one check for: commits, paths, regexes, or stopwords")
  57. }
  58. // Deduplicate commits and stopwords.
  59. if len(a.Commits) > 0 {
  60. uniqueCommits := make(map[string]struct{})
  61. for _, commit := range a.Commits {
  62. uniqueCommits[commit] = struct{}{}
  63. }
  64. a.Commits = maps.Keys(uniqueCommits)
  65. }
  66. if len(a.StopWords) > 0 {
  67. uniqueStopwords := make(map[string]struct{})
  68. for _, stopWord := range a.StopWords {
  69. uniqueStopwords[stopWord] = struct{}{}
  70. }
  71. a.StopWords = maps.Keys(uniqueStopwords)
  72. }
  73. a.validated = true
  74. return nil
  75. }
  76. // CommitAllowed returns true if the commit is allowed to be ignored.
  77. func (a *Allowlist) CommitAllowed(c string) (bool, string) {
  78. if a == nil || c == "" {
  79. return false, ""
  80. }
  81. for _, commit := range a.Commits {
  82. if commit == c {
  83. return true, c
  84. }
  85. }
  86. return false, ""
  87. }
  88. // PathAllowed returns true if the path is allowed to be ignored.
  89. func (a *Allowlist) PathAllowed(path string) bool {
  90. if a == nil || path == "" {
  91. return false
  92. }
  93. return anyRegexMatch(path, a.Paths)
  94. }
  95. // RegexAllowed returns true if the regex is allowed to be ignored.
  96. func (a *Allowlist) RegexAllowed(secret string) bool {
  97. if a == nil || secret == "" {
  98. return false
  99. }
  100. return anyRegexMatch(secret, a.Regexes)
  101. }
  102. func (a *Allowlist) ContainsStopWord(s string) (bool, string) {
  103. if a == nil || s == "" {
  104. return false, ""
  105. }
  106. s = strings.ToLower(s)
  107. for _, stopWord := range a.StopWords {
  108. if strings.Contains(s, strings.ToLower(stopWord)) {
  109. return true, stopWord
  110. }
  111. }
  112. return false, ""
  113. }