From d8070a94aa3096038d390db0f671c6ce9c4c1655 Mon Sep 17 00:00:00 2001 From: Romain Gaillard Date: Tue, 31 Dec 2024 16:35:49 +0100 Subject: [PATCH] Add more tests --- .../loki/secretfilter/secretfilter.go | 2 +- .../loki/secretfilter/secretfilter_test.go | 89 ++++++++++++++++++- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/internal/component/loki/secretfilter/secretfilter.go b/internal/component/loki/secretfilter/secretfilter.go index d7b9383b74..e609897813 100644 --- a/internal/component/loki/secretfilter/secretfilter.go +++ b/internal/component/loki/secretfilter/secretfilter.go @@ -244,7 +244,7 @@ func (c *Component) redactLine(line string, secret string, ruleName string) stri } if partialMask > 0 { // Don't apply partial masking if the secret is too short - if len(secret) > partialMask+2 { + if len(secret) > partialMask*2 { redactWith = secret[:partialMask] + redactWith } } diff --git a/internal/component/loki/secretfilter/secretfilter_test.go b/internal/component/loki/secretfilter/secretfilter_test.go index 5aa64f1c9c..ec2c248775 100644 --- a/internal/component/loki/secretfilter/secretfilter_test.go +++ b/internal/component/loki/secretfilter/secretfilter_test.go @@ -73,6 +73,16 @@ var customGitleaksConfig = map[string]string{ [[rules.allowlists]] regexes = ["abc\\d{3}", "fakeSecret[9]{5}"] `, + `allow_list_global`: ` + title = "gitleaks custom config" + + [[rules]] + id = "my-fake-secret" + description = "Identified a fake secret" + regex = '''(?i)\b(fakeSecret\d{5})(?:['|\"|\n|\r|\s|\x60|;]|$)''' + [allowlist] + regexes = ["abc\\d{3}", "fakeSecret[9]{5}"] + `, } var defaultRedactionString = "REDACTED-SECRET" @@ -321,15 +331,22 @@ var tt = []struct { "custom_gitleaks_file_allow_list_old", testConfigs["custom_gitleaks_file_simple"], customGitleaksConfig["allow_list_old"], - testLogs["simple_secret_custom-all9"].log, - testLogs["simple_secret_custom-all9"].log, // In the allowlist + testLogs["simple_secret_custom_all9"].log, + testLogs["simple_secret_custom_all9"].log, // In the allowlist }, { "custom_gitleaks_file_allow_list_new", testConfigs["custom_gitleaks_file_simple"], customGitleaksConfig["allow_list_new"], - testLogs["simple_secret_custom-all9"].log, - testLogs["simple_secret_custom-all9"].log, // In the allowlist + testLogs["simple_secret_custom_all9"].log, + testLogs["simple_secret_custom_all9"].log, // In the allowlist + }, + { + "custom_gitleaks_file_allow_list_old_redact", + testConfigs["custom_gitleaks_file_simple"], + customGitleaksConfig["allow_list_old"], + testLogs["simple_secret_custom"].log, + replaceSecrets(testLogs["simple_secret_custom"].log, testLogs["simple_secret_custom"].secrets, false, false, defaultRedactionString), }, { "custom_gitleaks_file_allow_list_new_redact", @@ -338,6 +355,20 @@ var tt = []struct { testLogs["simple_secret_custom"].log, replaceSecrets(testLogs["simple_secret_custom"].log, testLogs["simple_secret_custom"].secrets, false, false, defaultRedactionString), }, + { + "custom_gitleaks_file_allow_list_global", + testConfigs["custom_gitleaks_file_simple"], + customGitleaksConfig["allow_list_global"], + testLogs["simple_secret_custom_all9"].log, + testLogs["simple_secret_custom_all9"].log, // In the allowlist + }, + { + "custom_gitleaks_file_allow_list_global_redact", + testConfigs["custom_gitleaks_file_simple"], + customGitleaksConfig["allow_list_global"], + testLogs["simple_secret_custom"].log, + replaceSecrets(testLogs["simple_secret_custom"].log, testLogs["simple_secret_custom"].secrets, false, false, defaultRedactionString), + }, { "multiple_secrets", testConfigs["default"], @@ -355,12 +386,62 @@ func TestSecretFiltering(t *testing.T) { } } +func TestPartialMasking(t *testing.T) { + // Start testing with common cases + component := &Component{} + component.args = Arguments{PartialMask: 4} + // Too short to be partially masked + redacted := component.redactLine("This is a short secret abc123 in a log line", "abc123", "test-rule") + require.Equal(t, "This is a short secret in a log line", redacted) + + // Too short to be partially masked + redacted = component.redactLine("This is a longer secret abcd1234 in a log line", "abcd1234", "test-rule") + require.Equal(t, "This is a longer secret in a log line", redacted) + + // Will be partially masked + redacted = component.redactLine("This is a long enough secret abcd12345 in a log line", "abcd12345", "test-rule") + require.Equal(t, "This is a long enough secret abcd in a log line", redacted) + + // Will be partially masked + redacted = component.redactLine("This is the longest secret abcdef12345678 in a log line", "abcdef12345678", "test-rule") + require.Equal(t, "This is the longest secret abcd in a log line", redacted) + + // Test with different secret lengths and partial masking values + for _, partialMasking := range []int{1, 3, 4, 5, 9} { + for secretLength := range 30 { + if secretLength < 2 { + continue + } + expected := secretLength > partialMasking*2 + checkPartialMasking(t, partialMasking, secretLength, expected) + } + } +} + +func checkPartialMasking(t *testing.T, partialMasking int, secretLength int, partialRedactionExpected bool) { + component := &Component{} + component.args = Arguments{PartialMask: uint(partialMasking)} + secret := strings.Repeat("A", secretLength) + inputLog := fmt.Sprintf("This is a test with a secret %s in a log line", secret) + redacted := component.redactLine(inputLog, secret, "test-rule") + + prefix := "" + if partialRedactionExpected { + prefix = strings.Repeat("A", partialMasking) + } + expectedLog := fmt.Sprintf("This is a test with a secret %s in a log line", prefix) + require.Equal(t, expectedLog, redacted) +} + func runTest(t *testing.T, config string, gitLeaksConfigContent string, inputLog string, expectedLog string) { ch1 := loki.NewLogsReceiver() var args Arguments require.NoError(t, syntax.Unmarshal([]byte(config), &args)) args.ForwardTo = []loki.LogsReceiver{ch1} + // Making sure we're not testing with an empty log line by mistake + require.NotEmpty(t, inputLog) + // If needed, create a temporary gitleaks config file if args.GitleaksConfig != "" { args.GitleaksConfig = createTempGitleaksConfig(t, gitLeaksConfigContent)