rule.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. package config
  2. import (
  3. "regexp"
  4. "strings"
  5. )
  6. type Rule struct {
  7. Description string
  8. RuleID string
  9. Entropy float64
  10. EntropyReGroup int
  11. Regex *regexp.Regexp
  12. Path *regexp.Regexp
  13. Tags []string
  14. Allowlist Allowlist
  15. }
  16. func (r *Rule) IncludeEntropy(secret string) (bool, float64) {
  17. groups := r.Regex.FindStringSubmatch(secret)
  18. if len(groups)-1 > r.EntropyReGroup || len(groups) == 0 {
  19. // Config validation should prevent this
  20. return false, 0.0
  21. }
  22. // NOTE: this is a goofy hack to get around the fact there golang's regex engine
  23. // does not support positive lookaheads. Ideally we would want to add a
  24. // restriction on generic rules regex that requires the secret match group
  25. // contains both numbers and alphabetical characters. What this bit of code does is
  26. // check if the ruleid is prepended with "generic" and enforces the
  27. // secret contains both digits and alphabetical characters.
  28. if strings.HasPrefix(r.RuleID, "generic") {
  29. if !containsDigit(groups[r.EntropyReGroup]) {
  30. return false, 0.0
  31. }
  32. }
  33. // group = 0 will check the entropy of the whole regex match
  34. e := shannonEntropy(groups[r.EntropyReGroup])
  35. if e > r.Entropy {
  36. return true, e
  37. }
  38. return false, e
  39. }
  40. func (r *Rule) EntropySet() bool {
  41. if r.Entropy == 0.0 {
  42. return false
  43. }
  44. return true
  45. }