Repository: gitleaks/gitleaks
Pull request #1555 (2024-10-09 16:07:05)

Update base config allowlist
### Description:
This updates the config allowlist to ignore the following:

- String fmt placeholders (e.g., `%s`, `{0}`)
- Font file extensions
- Repeated characters (e.g., `*******`, `aaaaaaaaaaaaaaaaaaaa`)

### Checklist:

* [x] Does your PR pass tests?
* [x] Have you written new tests for your changes?
* [ ] Have you lint your code locally prior to submission?



Patch:
diff --git a/cmd/generate/config/base/config.go b/cmd/generate/config/base/config.go
index 2900132..540a91b 100644
--- a/cmd/generate/config/base/config.go
+++ b/cmd/generate/config/base/config.go
@@ -1,8 +1,10 @@
 package base
 
 import (
+	"fmt"
 	"github.com/zricethezav/gitleaks/v8/config"
 	"regexp"
+	"strings"
 )
 
 func CreateGlobalConfig() config.Config {
@@ -13,6 +15,27 @@ func CreateGlobalConfig() config.Config {
 			Regexes: []*regexp.Regexp{
 				// ----------- General placeholders -----------
 				regexp.MustCompile(`(?i)^true|false|null$`),
+				// Awkward workaround to detect repeated characters.
+				func() *regexp.Regexp {
+					var (
+						letters  = "abcdefghijklmnopqrstuvwxyz*."
+						patterns []string
+					)
+					for _, char := range letters {
+						if char == '*' || char == '.' {
+							patterns = append(patterns, fmt.Sprintf("\\%c+", char))
+						} else {
+							patterns = append(patterns, fmt.Sprintf("%c+", char))
+						}
+					}
+					return regexp.MustCompile("^(?i:" + strings.Join(patterns, "|") + ")$")
+				}(),
+
+				// ----------- Environment Variables -----------
+				regexp.MustCompile(`^\$(\d+|{\d+})$`),
+				regexp.MustCompile(`^\$([A-Z_]+|[a-z_]+)$`),
+				regexp.MustCompile(`^\${([A-Z_]+|[a-z_]+)}$`),
+
 				// ----------- Interpolated Variables -----------
 				// Ansible (https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html)
 				regexp.MustCompile(`^\{\{[ \t]*[\w ().|]+[ \t]*}}$`),
@@ -22,19 +45,18 @@ func CreateGlobalConfig() config.Config {
 				regexp.MustCompile(`^\$\{\{[ \t]*((env|github|secrets|vars)(\.[A-Za-z]\w+)+[\w "'&./=|]*)[ \t]*}}$`),
 				// NuGet (https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file#using-environment-variables)
 				regexp.MustCompile(`^%([A-Z_]+|[a-z_]+)%$`),
+				// String formatting.
+				regexp.MustCompile(`^%[+\-# 0]?[bcdeEfFgGoOpqstTUvxX]$`), // Golang (https://pkg.go.dev/fmt)
+				regexp.MustCompile(`^\{\d{0,2}}$`),                       // Python (https://docs.python.org/3/tutorial/inputoutput.html)
 				// Urban Code Deploy (https://www.ibm.com/support/pages/replace-token-step-replaces-replacement-values-windows-variables)
 				regexp.MustCompile(`^@([A-Z_]+|[a-z_]+)@$`),
-
-				// ----------- Environment Variables -----------
-				regexp.MustCompile(`^\$(\d+|{\d+})$`),
-				regexp.MustCompile(`^\$([A-Z_]+|[a-z_]+)$`),
-				regexp.MustCompile(`^\${([A-Z_]+|[a-z_]+)}$`),
 			},
 			Paths: []*regexp.Regexp{
 				regexp.MustCompile(`gitleaks\.toml`),
 
 				// ----------- Documents and media -----------
-				regexp.MustCompile(`(?i)\.(bmp|gif|jpe?g|svg|tiff?)$`),
+				regexp.MustCompile(`(?i)\.(bmp|gif|jpe?g|svg|tiff?)$`), // Images
+				regexp.MustCompile(`\.(eot|[ot]tf|woff2?)$`),           // Fonts
 				regexp.MustCompile(`(.*?)(doc|docx|zip|xls|pdf|bin|socket|vsidx|v2|suo|wsuo|.dll|pdb|exe|gltf)$`),
 
 				// ----------- Golang files -----------
diff --git a/config/gitleaks.toml b/config/gitleaks.toml
index c75cfe9..7e82c32 100644
--- a/config/gitleaks.toml
+++ b/config/gitleaks.toml
@@ -14,17 +14,21 @@ title = "gitleaks config"
 description = "global allow lists"
 regexes = [
     '''(?i)^true|false|null$''',
+    '''^(?i:a+|b+|c+|d+|e+|f+|g+|h+|i+|j+|k+|l+|m+|n+|o+|p+|q+|r+|s+|t+|u+|v+|w+|x+|y+|z+|\*+|\.+)$''',
+    '''^\$(\d+|{\d+})$''',
+    '''^\$([A-Z_]+|[a-z_]+)$''',
+    '''^\${([A-Z_]+|[a-z_]+)}$''',
     '''^\{\{[ \t]*[\w ().|]+[ \t]*}}$''',
     '''^\$\{\{[ \t]*((env|github|secrets|vars)(\.[A-Za-z]\w+)+[\w "'&./=|]*)[ \t]*}}$''',
     '''^%([A-Z_]+|[a-z_]+)%$''',
+    '''^%[+\-# 0]?[bcdeEfFgGoOpqstTUvxX]$''',
+    '''^\{\d{0,2}}$''',
     '''^@([A-Z_]+|[a-z_]+)@$''',
-    '''^\$(\d+|{\d+})$''',
-    '''^\$([A-Z_]+|[a-z_]+)$''',
-    '''^\${([A-Z_]+|[a-z_]+)}$''',
 ]
 paths = [
     '''gitleaks\.toml''',
     '''(?i)\.(bmp|gif|jpe?g|svg|tiff?)$''',
+    '''\.(eot|[ot]tf|woff2?)$''',
     '''(.*?)(doc|docx|zip|xls|pdf|bin|socket|vsidx|v2|suo|wsuo|.dll|pdb|exe|gltf)$''',
     '''go\.(mod|sum|work(\.sum)?)$''',
     '''(^|/)vendor/modules\.txt$''',


Test patch:
diff --git a/cmd/generate/config/base/config_test.go b/cmd/generate/config/base/config_test.go
index 0c2316b..2f64171 100644
--- a/cmd/generate/config/base/config_test.go
+++ b/cmd/generate/config/base/config_test.go
@@ -14,6 +14,16 @@ func TestConfigAllowlistRegexes(t *testing.T) {
 				`true`, `True`, `false`, `False`, `null`, `NULL`,
 			},
 		},
+		"general placeholders - repeated characters": {
+			invalid: []string{
+				`aaaaaaaaaaaaaaaaa`, `BBBBBBBBBBbBBBBBBBbBB`, `********************`,
+			},
+			valid: []string{`aaaaaaaaaaaaaaaaaaabaa`, `pas*************d`},
+		},
+		"environment variables": {
+			invalid: []string{`$2`, `$GIT_PASSWORD`, `${GIT_PASSWORD}`, `$password`},
+			valid:   []string{`$yP@R.@=ibxI`, `$2a6WCust9aE`, `${not_complete1`},
+		},
 		"interpolated variables - ansible": {
 			invalid: []string{
 				`{{ x }}`, `{{ password }}`, `{{password}}`, `{{ data.proxy_password }}`,
@@ -39,14 +49,20 @@ func TestConfigAllowlistRegexes(t *testing.T) {
 				`%MY_PASSWORD%`, `%password%`,
 			},
 		},
+		"interpolated variables - string fmt - golang": {
+			invalid: []string{
+				`%b`, `%c`, `%d`, `% d`, `%e`, `%E`, `%f`, `%F`, `%g`, `%G`, `%o`, `%O`, `%p`, `%q`, `%-s`, `%s`, `%t`, `%T`, `%U`, `%#U`, `%+v`, `%#v`, `%v`, `%x`, `%X`,
+			},
+		},
+		"interpolated variables - string fmt - python": {
+			invalid: []string{
+				`{}`, `{0}`, `{10}`,
+			},
+		},
 		"interpolated variables - ucd": {
 			invalid: []string{`@password@`, `@LDAP_PASS@`},
 			valid:   []string{`@username@mastodon.example`},
 		},
-		"environment variables": {
-			invalid: []string{`$2`, `$GIT_PASSWORD`, `${GIT_PASSWORD}`, `$password`},
-			valid:   []string{`$yP@R.@=ibxI`, `$2a6WCust9aE`, `${not_complete1`},
-		},
 	}
 
 	cfg := CreateGlobalConfig()