detect.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // The `detect` and `protect` command is now deprecated. Here are some equivalent commands
  2. // to help guide you.
  3. // OLD CMD: gitleaks detect --source={repo}
  4. // NEW CMD: gitleaks git {repo}
  5. // OLD CMD: gitleaks protect --source={repo}
  6. // NEW CMD: gitleaks git --pre-commit {repo}
  7. // OLD CMD: gitleaks protect --staged --source={repo}
  8. // NEW CMD: gitleaks git --pre-commit --staged {repo}
  9. // OLD CMD: gitleaks detect --no-git --source={repo}
  10. // NEW CMD: gitleaks directory {directory/file}
  11. // OLD CMD: gitleaks detect --no-git --pipe
  12. // NEW CMD: gitleaks stdin
  13. package cmd
  14. import (
  15. "os"
  16. "time"
  17. "github.com/spf13/cobra"
  18. "github.com/zricethezav/gitleaks/v8/logging"
  19. "github.com/zricethezav/gitleaks/v8/report"
  20. "github.com/zricethezav/gitleaks/v8/sources"
  21. )
  22. func init() {
  23. rootCmd.AddCommand(detectCmd)
  24. detectCmd.Flags().Bool("no-git", false, "treat git repo as a regular directory and scan those files, --log-opts has no effect on the scan when --no-git is set")
  25. detectCmd.Flags().Bool("pipe", false, "scan input from stdin, ex: `cat some_file | gitleaks detect --pipe`")
  26. detectCmd.Flags().Bool("follow-symlinks", false, "scan files that are symlinks to other files")
  27. detectCmd.Flags().StringP("source", "s", ".", "path to source")
  28. detectCmd.Flags().String("log-opts", "", "git log options")
  29. }
  30. var detectCmd = &cobra.Command{
  31. Use: "detect",
  32. Short: "detect secrets in code",
  33. Run: runDetect,
  34. Hidden: true,
  35. }
  36. func runDetect(cmd *cobra.Command, args []string) {
  37. source, err := cmd.Flags().GetString("source")
  38. if err != nil {
  39. logging.Fatal().Err(err).Msg("could not get source")
  40. }
  41. initConfig(source)
  42. var findings []report.Finding
  43. // setup config (aka, the thing that defines rules)
  44. cfg := Config(cmd)
  45. // start timer
  46. start := time.Now()
  47. detector := Detector(cmd, cfg, source)
  48. // set follow symlinks flag
  49. if detector.FollowSymlinks, err = cmd.Flags().GetBool("follow-symlinks"); err != nil {
  50. logging.Fatal().Err(err).Msg("")
  51. }
  52. // set exit code
  53. exitCode, err := cmd.Flags().GetInt("exit-code")
  54. if err != nil {
  55. logging.Fatal().Err(err).Msg("could not get exit code")
  56. }
  57. // determine what type of scan:
  58. // - git: scan the history of the repo
  59. // - no-git: scan files by treating the repo as a plain directory
  60. noGit, err := cmd.Flags().GetBool("no-git")
  61. if err != nil {
  62. logging.Fatal().Err(err).Msg("could not call GetBool() for no-git")
  63. }
  64. fromPipe, err := cmd.Flags().GetBool("pipe")
  65. if err != nil {
  66. logging.Fatal().Err(err).Msg("could not call GetBool() for pipe")
  67. }
  68. // start the detector scan
  69. if noGit {
  70. var paths <-chan sources.ScanTarget
  71. paths, err = sources.DirectoryTargets(
  72. source,
  73. detector.Sema,
  74. detector.FollowSymlinks,
  75. detector.Config.Allowlist.PathAllowed,
  76. )
  77. if err != nil {
  78. logging.Fatal().Err(err)
  79. }
  80. findings, err = detector.DetectFiles(paths)
  81. if err != nil {
  82. // don't exit on error, just log it
  83. logging.Error().Err(err).Msg("failed scan directory")
  84. }
  85. } else if fromPipe {
  86. findings, err = detector.DetectReader(os.Stdin, 10)
  87. if err != nil {
  88. // log fatal to exit, no need to continue since a report
  89. // will not be generated when scanning from a pipe...for now
  90. logging.Fatal().Err(err).Msg("failed scan input from stdin")
  91. }
  92. } else {
  93. var (
  94. gitCmd *sources.GitCmd
  95. logOpts string
  96. )
  97. logOpts, err = cmd.Flags().GetString("log-opts")
  98. if err != nil {
  99. logging.Fatal().Err(err).Msg("could not call GetString() for log-opts")
  100. }
  101. gitCmd, err = sources.NewGitLogCmd(source, logOpts)
  102. if err != nil {
  103. logging.Fatal().Err(err).Msg("could not create Git cmd")
  104. }
  105. findings, err = detector.DetectGit(gitCmd)
  106. if err != nil {
  107. // don't exit on error, just log it
  108. logging.Error().Err(err).Msg("failed to scan Git repository")
  109. }
  110. }
  111. findingSummaryAndExit(detector, findings, exitCode, start, err)
  112. }