detect_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package detect
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "testing"
  6. "github.com/spf13/viper"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/zricethezav/gitleaks/v8/config"
  9. "github.com/zricethezav/gitleaks/v8/report"
  10. )
  11. func TestDetectFindings(t *testing.T) {
  12. tests := []struct {
  13. cfgName string
  14. opts Options
  15. filePath string
  16. bytes []byte
  17. commit string
  18. expectedFindings []report.Finding
  19. wantError error
  20. }{
  21. {
  22. cfgName: "simple",
  23. bytes: []byte(`awsToken := \"AKIALALEMEL33243OLIA\"`),
  24. filePath: "tmp.go",
  25. expectedFindings: []report.Finding{
  26. {
  27. Description: "AWS Access Key",
  28. Secret: "AKIALALEMEL33243OLIA",
  29. Match: "AKIALALEMEL33243OLIA",
  30. File: "tmp.go",
  31. RuleID: "aws-access-key",
  32. Tags: []string{"key", "AWS"},
  33. StartLine: 1,
  34. EndLine: 1,
  35. StartColumn: 15,
  36. EndColumn: 34,
  37. },
  38. },
  39. },
  40. {
  41. cfgName: "allow_aws_re",
  42. bytes: []byte(`awsToken := \"AKIALALEMEL33243OLIA\"`),
  43. filePath: "tmp.go",
  44. expectedFindings: []report.Finding{},
  45. },
  46. {
  47. cfgName: "allow_path",
  48. bytes: []byte(`awsToken := \"AKIALALEMEL33243OLIA\"`),
  49. filePath: "tmp.go",
  50. expectedFindings: []report.Finding{},
  51. },
  52. {
  53. cfgName: "allow_commit",
  54. bytes: []byte(`awsToken := \"AKIALALEMEL33243OLIA\"`),
  55. filePath: "tmp.go",
  56. expectedFindings: []report.Finding{},
  57. commit: "allowthiscommit",
  58. },
  59. {
  60. cfgName: "entropy_group",
  61. bytes: []byte(`const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`),
  62. filePath: "tmp.go",
  63. expectedFindings: []report.Finding{
  64. {
  65. Description: "Discord API key",
  66. Match: "Discord_Public_Key = \"e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5\"",
  67. Secret: "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5",
  68. File: "tmp.go",
  69. RuleID: "discord-api-key",
  70. Tags: []string{},
  71. Entropy: 3.7906237,
  72. StartLine: 1,
  73. EndLine: 1,
  74. StartColumn: 7,
  75. EndColumn: 93,
  76. },
  77. },
  78. },
  79. {
  80. cfgName: "generic_with_py_path",
  81. bytes: []byte(`const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`),
  82. filePath: "tmp.go",
  83. expectedFindings: []report.Finding{},
  84. },
  85. {
  86. cfgName: "generic_with_py_path",
  87. bytes: []byte(`const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`),
  88. filePath: "tmp.py",
  89. expectedFindings: []report.Finding{
  90. {
  91. Description: "Generic API Key",
  92. Match: "Key = \"e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5\"",
  93. Secret: "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5",
  94. File: "tmp.py",
  95. RuleID: "generic-api-key",
  96. Tags: []string{},
  97. Entropy: 3.7906237,
  98. StartLine: 1,
  99. EndLine: 1,
  100. StartColumn: 22,
  101. EndColumn: 93,
  102. },
  103. },
  104. },
  105. {
  106. cfgName: "path_only",
  107. bytes: []byte(`const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`),
  108. filePath: "tmp.py",
  109. expectedFindings: []report.Finding{
  110. {
  111. Description: "Python Files",
  112. Match: "file detected: tmp.py",
  113. File: "tmp.py",
  114. RuleID: "python-files-only",
  115. Tags: []string{},
  116. },
  117. },
  118. },
  119. {
  120. cfgName: "bad_entropy_group",
  121. bytes: []byte(`const Discord_Public_Key = "e7322523fb86ed64c836a979cf8465fbd436378c653c1db38f9ae87bc62a6fd5"`),
  122. filePath: "tmp.go",
  123. expectedFindings: []report.Finding{},
  124. wantError: fmt.Errorf("Discord API key invalid regex secret group 5, max regex secret group 3"),
  125. },
  126. {
  127. cfgName: "simple",
  128. bytes: []byte(`awsToken := \"AKIALALEMEL33243OLIA\"`),
  129. filePath: filepath.Join(configPath, "simple.toml"),
  130. expectedFindings: []report.Finding{},
  131. },
  132. {
  133. cfgName: "allow_global_aws_re",
  134. bytes: []byte(`awsToken := \"AKIALALEMEL33243OLIA\"`),
  135. filePath: "tmp.go",
  136. expectedFindings: []report.Finding{},
  137. },
  138. }
  139. for _, tt := range tests {
  140. viper.Reset()
  141. viper.AddConfigPath(configPath)
  142. viper.SetConfigName(tt.cfgName)
  143. viper.SetConfigType("toml")
  144. err := viper.ReadInConfig()
  145. if err != nil {
  146. t.Error(err)
  147. }
  148. var vc config.ViperConfig
  149. viper.Unmarshal(&vc)
  150. cfg, err := vc.Translate()
  151. cfg.Path = filepath.Join(configPath, tt.cfgName+".toml")
  152. if tt.wantError != nil {
  153. if err == nil {
  154. t.Errorf("expected error")
  155. }
  156. assert.Equal(t, tt.wantError, err)
  157. }
  158. findings := DetectFindings(cfg, tt.bytes, tt.filePath, tt.commit)
  159. assert.ElementsMatch(t, tt.expectedFindings, findings)
  160. }
  161. }