leak.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package scan
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math"
  6. "strings"
  7. "time"
  8. "github.com/zricethezav/gitleaks/v7/options"
  9. "github.com/go-git/go-git/v5/plumbing/object"
  10. )
  11. // Leak is a struct that contains information about some line of code that contains
  12. // sensitive information as determined by the rules set in a gitleaks config
  13. type Leak struct {
  14. Line string `json:"line"`
  15. LineNumber int `json:"lineNumber"`
  16. Offender string `json:"offender"`
  17. OffenderEntropy float64 `json:"offenderEntropy"`
  18. Commit string `json:"commit"`
  19. Repo string `json:"repo"`
  20. RepoURL string `json:"repoURL"`
  21. LeakURL string `json:"leakURL"`
  22. Rule string `json:"rule"`
  23. Message string `json:"commitMessage"`
  24. Author string `json:"author"`
  25. Email string `json:"email"`
  26. File string `json:"file"`
  27. Date time.Time `json:"date"`
  28. Tags string `json:"tags"`
  29. }
  30. // RedactLeak will replace the offending string with "REDACTED" in both
  31. // the offender and line field of the leak which.
  32. func RedactLeak(leak Leak) Leak {
  33. leak.Line = strings.Replace(leak.Line, leak.Offender, "REDACTED", -1)
  34. leak.Offender = "REDACTED"
  35. return leak
  36. }
  37. // NewLeak creates a new leak from common data all leaks must have, line, offender, linenumber
  38. func NewLeak(line string, offender string, lineNumber int) Leak {
  39. return Leak{
  40. Line: line,
  41. Offender: offender,
  42. LineNumber: lineNumber,
  43. OffenderEntropy: -1, // -1 means not checked
  44. }
  45. }
  46. // WithCommit adds commit data to the leak
  47. func (leak Leak) WithCommit(commit *object.Commit) Leak {
  48. leak.Commit = commit.Hash.String()
  49. leak.Author = commit.Author.Name
  50. leak.Email = commit.Author.Email
  51. leak.Message = commit.Message
  52. leak.Date = commit.Author.When
  53. return leak
  54. }
  55. // WithEntropy adds OffenderEntropy data to the leak
  56. func (leak Leak) WithEntropy(entropyLevel float64) Leak {
  57. leak.OffenderEntropy = math.Round(entropyLevel*1000) / 1000
  58. return leak
  59. }
  60. // Log logs a leak and redacts if necessary
  61. func (leak Leak) Log(opts options.Options) {
  62. if !opts.Quiet && !opts.Verbose {
  63. return
  64. }
  65. if opts.Redact {
  66. leak = RedactLeak(leak)
  67. }
  68. if opts.Quiet {
  69. var b []byte
  70. b, _ = json.Marshal(leak)
  71. fmt.Println(string(b))
  72. } else {
  73. var b []byte
  74. b, _ = json.MarshalIndent(leak, "", " ")
  75. fmt.Println(string(b))
  76. }
  77. }
  78. // URL generates a url to the leak if leak.RepoURL is set
  79. func (leak Leak) URL() string {
  80. if leak.RepoURL != "" {
  81. return fmt.Sprintf("%s/blob/%s/%s#L%d", leak.RepoURL, leak.Commit, leak.File, leak.LineNumber)
  82. }
  83. return ""
  84. }