diff --git a/pkg/fanal/secret/builtin-rules.go b/pkg/fanal/secret/builtin-rules.go index b868967b669..4c434e89253 100644 --- a/pkg/fanal/secret/builtin-rules.go +++ b/pkg/fanal/secret/builtin-rules.go @@ -68,6 +68,7 @@ var ( CategoryLinkedIn = types.SecretRuleCategory("LinkedIn") CategoryTwitch = types.SecretRuleCategory("Twitch") CategoryTypeform = types.SecretRuleCategory("Typeform") + CategoryDocker = types.SecretRuleCategory("Docker") ) // Reusable regex patterns @@ -792,4 +793,13 @@ var builtinRules = []Rule{ SecretGroupName: "secret", Keywords: []string{"typeform"}, }, + { + ID: "dockerconfig-secret", + Category: CategoryDocker, + Title: "Dockerconfig secret exposed", + Severity: "HIGH", + Regex: MustCompile(`(?i)(\.(dockerconfigjson|dockercfg):\s*\|*\s*(?P(ey|ew)+[A-Za-z0-9\/\+=]+))`), + SecretGroupName: "secret", + Keywords: []string{"dockerc"}, + }, } diff --git a/pkg/fanal/secret/scanner_test.go b/pkg/fanal/secret/scanner_test.go index 659b1f91a17..2fe6c773634 100644 --- a/pkg/fanal/secret/scanner_test.go +++ b/pkg/fanal/secret/scanner_test.go @@ -526,6 +526,68 @@ func TestSecretScanner(t *testing.T) { }, }, } + wantFindingDockerKey1 := types.SecretFinding{ + RuleID: "dockerconfig-secret", + Category: secret.CategoryDocker, + Title: "Dockerconfig secret exposed", + Severity: "HIGH", + StartLine: 4, + EndLine: 4, + Match: " .dockercfg: ************", + Code: types.Code{ + Lines: []types.Line{ + { + Number: 2, + Content: " .dockerconfigjson: ************", + Highlighted: " .dockerconfigjson: ************", + }, + { + Number: 3, + Content: "data2:", + Highlighted: "data2:", + }, + { + Number: 4, + Content: " .dockercfg: ************", + Highlighted: " .dockercfg: ************", + IsCause: true, + FirstCause: true, + LastCause: true, + }, + }, + }, + } + wantFindingDockerKey2 := types.SecretFinding{ + RuleID: "dockerconfig-secret", + Category: secret.CategoryDocker, + Title: "Dockerconfig secret exposed", + Severity: "HIGH", + StartLine: 2, + EndLine: 2, + Match: " .dockerconfigjson: ************", + Code: types.Code{ + Lines: []types.Line{ + { + Number: 1, + Content: "data1:", + Highlighted: "data1:", + }, + { + Number: 2, + Content: " .dockerconfigjson: ************", + Highlighted: " .dockerconfigjson: ************", + IsCause: true, + FirstCause: true, + LastCause: true, + }, + { + Number: 3, + Content: "data2:", + Highlighted: "data2:", + }, + }, + }, + } wantMultiLine := types.SecretFinding{ RuleID: "multi-line-secret", Category: "general", @@ -609,6 +671,15 @@ func TestSecretScanner(t *testing.T) { Findings: []types.SecretFinding{wantFindingAsymmetricPrivateKeyJson}, }, }, + { + name: "find Docker registry credentials", + configPath: filepath.Join("testdata", "skip-test.yaml"), + inputFilePath: filepath.Join("testdata", "docker-secrets.txt"), + want: types.Secret{ + FilePath: filepath.Join("testdata", "docker-secrets.txt"), + Findings: []types.SecretFinding{wantFindingDockerKey1, wantFindingDockerKey2}, + }, + }, { name: "include when keyword found", configPath: filepath.Join("testdata", "config-happy-keywords.yaml"), diff --git a/pkg/fanal/secret/testdata/docker-secrets.txt b/pkg/fanal/secret/testdata/docker-secrets.txt new file mode 100644 index 00000000000..9bd5b12cfd3 --- /dev/null +++ b/pkg/fanal/secret/testdata/docker-secrets.txt @@ -0,0 +1,4 @@ +data1: + .dockerconfigjson: eyE1x2a3MpLe +data2: + .dockercfg: ewE1x2a3MpLe \ No newline at end of file