report.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package scan
  2. import (
  3. "encoding/csv"
  4. "encoding/json"
  5. "os"
  6. "time"
  7. "github.com/sirupsen/logrus"
  8. "github.com/zricethezav/gitleaks/v7/config"
  9. "github.com/zricethezav/gitleaks/v7/options"
  10. "github.com/zricethezav/gitleaks/v7/version"
  11. )
  12. // Report is a container for leaks and number of commits scanned
  13. type Report struct {
  14. Leaks []Leak
  15. Commits int
  16. }
  17. // WriteReport accepts a report and options and will write a report if --report has been set
  18. func WriteReport(report Report, opts options.Options, cfg config.Config) error {
  19. if !(opts.NoGit || opts.CheckUncommitted()) {
  20. logrus.Info("commits scanned: ", report.Commits)
  21. }
  22. if len(report.Leaks) != 0 {
  23. logrus.Warn("leaks found: ", len(report.Leaks))
  24. } else {
  25. logrus.Info("No leaks found")
  26. }
  27. if opts.Report == "" {
  28. return nil
  29. }
  30. if opts.Redact {
  31. var redactedLeaks []Leak
  32. for _, leak := range report.Leaks {
  33. redactedLeaks = append(redactedLeaks, RedactLeak(leak))
  34. }
  35. report.Leaks = redactedLeaks
  36. }
  37. file, err := os.Create(opts.Report)
  38. if err != nil {
  39. return err
  40. }
  41. defer rable(file.Close)
  42. if opts.Report != "" {
  43. switch opts.ReportFormat {
  44. case "json":
  45. encoder := json.NewEncoder(file)
  46. encoder.SetIndent("", " ")
  47. err = encoder.Encode(report.Leaks)
  48. if err != nil {
  49. return err
  50. }
  51. case "csv":
  52. w := csv.NewWriter(file)
  53. err = w.Write([]string{"repo", "line", "commit", "offender", "leakURL", "rule", "tags", "commitMsg", "author", "email", "file", "date"})
  54. if err != nil {
  55. return err
  56. }
  57. for _, leak := range report.Leaks {
  58. err := w.Write([]string{leak.Repo, leak.Line, leak.Commit, leak.Offender, leak.LeakURL, leak.Rule, leak.Tags, leak.Message, leak.Author, leak.Email, leak.File, leak.Date.Format(time.RFC3339)})
  59. if err != nil {
  60. return err
  61. }
  62. }
  63. w.Flush()
  64. case "sarif":
  65. s := Sarif{
  66. Schema: "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
  67. Version: "2.1.0",
  68. Runs: []Runs{
  69. {
  70. Tool: Tool{
  71. Driver: Driver{
  72. Name: "Gitleaks",
  73. SemanticVersion: version.Version,
  74. Rules: configToRules(cfg),
  75. },
  76. },
  77. Results: leaksToResults(report.Leaks),
  78. },
  79. },
  80. }
  81. encoder := json.NewEncoder(file)
  82. encoder.SetIndent("", " ")
  83. err = encoder.Encode(s)
  84. if err != nil {
  85. return err
  86. }
  87. }
  88. }
  89. return nil
  90. }