config.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package config
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strconv"
  6. "github.com/zricethezav/gitleaks/v3/options"
  7. "github.com/BurntSushi/toml"
  8. )
  9. // Whitelist is struct containing items that if encountered will whitelist
  10. // a commit/line of code that would be considered a leak.
  11. type Whitelist struct {
  12. Description string
  13. Regex *regexp.Regexp
  14. File *regexp.Regexp
  15. }
  16. // entropy represents an entropy range
  17. type Entropy struct {
  18. Min float64
  19. Max float64
  20. Group int
  21. }
  22. // Rule is a struct that contains information that is loaded from a gitleaks config.
  23. // This struct is used in the Config struct as an array of Rules and is iterated
  24. // over during an audit. Each rule will be checked. If a regex match is found AND
  25. // that match is not whitelisted (globally or locally), then a leak will be appended
  26. // to the final audit report.
  27. type Rule struct {
  28. Description string
  29. Regex *regexp.Regexp
  30. Tags []string
  31. Whitelist []Whitelist
  32. Entropies []Entropy
  33. }
  34. // Config is a composite struct of Rules and Whitelists
  35. // Each Rule contains a description, regular expression, tags, and whitelists if available
  36. type Config struct {
  37. FileRegex *regexp.Regexp
  38. Message *regexp.Regexp
  39. Rules []Rule
  40. Whitelist struct {
  41. Description string
  42. Commits []string
  43. File *regexp.Regexp
  44. }
  45. }
  46. // TomlLoader gets loaded with the values from a gitleaks toml config
  47. // see the config in config/defaults.go for an example. TomlLoader is used
  48. // to generate Config values (compiling regexes, etc).
  49. type TomlLoader struct {
  50. Global struct {
  51. File string
  52. Message string
  53. }
  54. Whitelist struct {
  55. Description string
  56. Commits []string
  57. File string
  58. }
  59. Rules []struct {
  60. Description string
  61. Regex string
  62. Tags []string
  63. Entropies []struct {
  64. Min string
  65. Max string
  66. Group string
  67. }
  68. Whitelist []struct {
  69. Description string
  70. Regex string
  71. File string
  72. }
  73. }
  74. }
  75. // NewConfig will create a new config struct which contains
  76. // rules on how gitleaks will proceed with its audit.
  77. // If no options are passed via cli then NewConfig will return
  78. // a default config which can be seen in config.go
  79. func NewConfig(options options.Options) (Config, error) {
  80. var cfg Config
  81. tomlLoader := TomlLoader{}
  82. var err error
  83. if options.Config != "" {
  84. _, err = toml.DecodeFile(options.Config, &tomlLoader)
  85. } else {
  86. _, err = toml.Decode(DefaultConfig, &tomlLoader)
  87. }
  88. if err != nil {
  89. return cfg, err
  90. }
  91. cfg, err = tomlLoader.Parse()
  92. if err != nil {
  93. return cfg, err
  94. }
  95. return cfg, nil
  96. }
  97. // Parse will parse the values set in a TomlLoader and use those values
  98. // to create compiled regular expressions and rules used in audits
  99. func (tomlLoader TomlLoader) Parse() (Config, error) {
  100. var cfg Config
  101. for _, rule := range tomlLoader.Rules {
  102. re, err := regexp.Compile(rule.Regex)
  103. if err != nil {
  104. return cfg, fmt.Errorf("problem loading config: %v", err)
  105. }
  106. // rule specific whitelists
  107. var whitelists []Whitelist
  108. for _, wl := range rule.Whitelist {
  109. re, err := regexp.Compile(wl.Regex)
  110. if err != nil {
  111. return cfg, fmt.Errorf("problem loading config: %v", err)
  112. }
  113. fileRe, err := regexp.Compile(wl.File)
  114. if err != nil {
  115. return cfg, fmt.Errorf("problem loading config: %v", err)
  116. }
  117. whitelists = append(whitelists, Whitelist{
  118. Description: wl.Description,
  119. File: fileRe,
  120. Regex: re,
  121. })
  122. }
  123. var entropies []Entropy
  124. for _, e := range rule.Entropies {
  125. min, err := strconv.ParseFloat(e.Min, 64)
  126. if err != nil {
  127. return cfg, err
  128. }
  129. max, err := strconv.ParseFloat(e.Max, 64)
  130. if err != nil {
  131. return cfg, err
  132. }
  133. if e.Group == "" {
  134. e.Group = "0"
  135. }
  136. group, err := strconv.ParseInt(e.Group, 10, 64)
  137. if err != nil {
  138. return cfg, err
  139. } else if int(group) >= len(re.SubexpNames()) {
  140. return cfg, fmt.Errorf("problem loading config: group cannot be higher than number of groups in regexp")
  141. } else if group < 0 {
  142. return cfg, fmt.Errorf("problem loading config: group cannot be lower than 0")
  143. } else if min > 8.0 || min < 0.0 || max > 8.0 || max < 0.0 {
  144. return cfg, fmt.Errorf("problem loading config: invalid entropy ranges, must be within 0.0-8.0")
  145. } else if min > max {
  146. return cfg, fmt.Errorf("problem loading config: entropy Min value cannot be higher than Max value")
  147. }
  148. entropies = append(entropies, Entropy{Min: min, Max: max, Group: int(group)})
  149. }
  150. cfg.Rules = append(cfg.Rules, Rule{
  151. Description: rule.Description,
  152. Regex: re,
  153. Tags: rule.Tags,
  154. Whitelist: whitelists,
  155. Entropies: entropies,
  156. })
  157. }
  158. // global leaks
  159. if tomlLoader.Global.File != "" {
  160. re, err := regexp.Compile(tomlLoader.Global.File)
  161. if err != nil {
  162. return cfg, fmt.Errorf("problem loading config: %v", err)
  163. }
  164. cfg.FileRegex = re
  165. }
  166. if tomlLoader.Global.Message != "" {
  167. re, err := regexp.Compile(tomlLoader.Global.Message)
  168. if err != nil {
  169. return cfg, fmt.Errorf("problem loading config: %v", err)
  170. }
  171. cfg.Message = re
  172. }
  173. // global whitelists
  174. if tomlLoader.Whitelist.File != "" {
  175. re, err := regexp.Compile(tomlLoader.Whitelist.File)
  176. if err != nil {
  177. return cfg, fmt.Errorf("problem loading config: %v", err)
  178. }
  179. cfg.Whitelist.File = re
  180. }
  181. cfg.Whitelist.Commits = tomlLoader.Whitelist.Commits
  182. cfg.Whitelist.Description = tomlLoader.Whitelist.Description
  183. return cfg, nil
  184. }