report.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. return nil
  27. }
  28. if opts.Report == "" {
  29. return nil
  30. }
  31. if opts.Redact {
  32. var redactedLeaks []Leak
  33. for _, leak := range report.Leaks {
  34. redactedLeaks = append(redactedLeaks, RedactLeak(leak))
  35. }
  36. report.Leaks = redactedLeaks
  37. }
  38. file, err := os.Create(opts.Report)
  39. if err != nil {
  40. return err
  41. }
  42. defer file.Close()
  43. if opts.Report != "" {
  44. switch opts.ReportFormat {
  45. case "json":
  46. encoder := json.NewEncoder(file)
  47. encoder.SetIndent("", " ")
  48. err = encoder.Encode(report.Leaks)
  49. if err != nil {
  50. return err
  51. }
  52. case "csv":
  53. w := csv.NewWriter(file)
  54. _ = w.Write([]string{"repo", "line", "commit", "offender", "leakURL", "rule", "tags", "commitMsg", "author", "email", "file", "date"})
  55. for _, leak := range report.Leaks {
  56. 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)})
  57. }
  58. w.Flush()
  59. case "sarif":
  60. s := Sarif{
  61. Schema: "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
  62. Version: "2.1.0",
  63. Runs: []Runs{
  64. {
  65. Tool: Tool{
  66. Driver: Driver{
  67. Name: "Gitleaks",
  68. SemanticVersion: version.Version,
  69. Rules: configToRules(cfg),
  70. },
  71. },
  72. Results: leaksToResults(report.Leaks),
  73. },
  74. },
  75. }
  76. encoder := json.NewEncoder(file)
  77. encoder.SetIndent("", " ")
  78. err = encoder.Encode(s)
  79. if err != nil {
  80. return err
  81. }
  82. }
  83. }
  84. return nil
  85. }