detect.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package detect
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "regexp"
  6. "strings"
  7. "github.com/zricethezav/gitleaks/v8/config"
  8. "github.com/zricethezav/gitleaks/v8/report"
  9. )
  10. type Options struct {
  11. Verbose bool
  12. Redact bool
  13. }
  14. func DetectFindings(cfg config.Config, b []byte, filePath string, commit string) []report.Finding {
  15. var findings []report.Finding
  16. linePairs := regexp.MustCompile("\n").FindAllIndex(b, -1)
  17. // check if we should skip file based on the global allowlist
  18. if cfg.Allowlist.PathAllowed(filePath) {
  19. return findings
  20. }
  21. for _, r := range cfg.Rules {
  22. pathSkip := false
  23. if r.Allowlist.CommitAllowed(commit) {
  24. continue
  25. }
  26. if r.Allowlist.PathAllowed(filePath) {
  27. continue
  28. }
  29. // Check if path should be considered
  30. if r.Path != nil {
  31. if r.Path.Match([]byte(filePath)) {
  32. if r.Regex == nil {
  33. // This is a path only rule
  34. f := report.Finding{
  35. Description: r.Description,
  36. File: filePath,
  37. RuleID: r.RuleID,
  38. Context: fmt.Sprintf("file detected: %s", filePath),
  39. Tags: r.Tags,
  40. }
  41. findings = append(findings, f)
  42. pathSkip = true
  43. }
  44. } else {
  45. pathSkip = true
  46. }
  47. }
  48. if pathSkip {
  49. continue
  50. }
  51. matchIndices := r.Regex.FindAllIndex(b, -1)
  52. for _, m := range matchIndices {
  53. location := getLocation(linePairs, m[0], m[1])
  54. f := report.Finding{
  55. Description: r.Description,
  56. File: filePath,
  57. RuleID: r.RuleID,
  58. StartLine: location.startLine,
  59. EndLine: location.endLine,
  60. StartColumn: location.startColumn,
  61. EndColumn: location.endColumn,
  62. Secret: strings.Trim(string(b[m[0]:m[1]]), "\n"),
  63. Context: limit(strings.Trim(string(b[location.startLineIndex:location.endLineIndex]), "\n")),
  64. Tags: r.Tags,
  65. }
  66. if r.Allowlist.RegexAllowed(f.Secret) {
  67. continue
  68. }
  69. if r.EntropySet() {
  70. include, entropy := r.IncludeEntropy(strings.Trim(string(b[m[0]:m[1]]), "\n"))
  71. if include {
  72. f.Entropy = float32(entropy)
  73. findings = append(findings, f)
  74. }
  75. } else {
  76. findings = append(findings, f)
  77. }
  78. }
  79. }
  80. return findings
  81. }
  82. func limit(s string) string {
  83. if len(s) > 500 {
  84. return s[:500] + "..."
  85. }
  86. return s
  87. }
  88. func printFinding(f report.Finding) {
  89. var b []byte
  90. b, _ = json.MarshalIndent(f, "", " ")
  91. fmt.Println(string(b))
  92. }