瀏覽代碼

fix: Redact password arguments in logs #594 (#601)

James Read 1 年之前
父節點
當前提交
1ffdd93ddf
共有 2 個文件被更改,包括 57 次插入1 次删除
  1. 23 1
      service/internal/executor/arguments.go
  2. 34 0
      service/internal/executor/arguments_test.go

+ 23 - 1
service/internal/executor/arguments.go

@@ -67,6 +67,7 @@ func parseActionArguments(values map[string]string, action *config.Action, entit
 
 	parsedShellCommand, err := parseCommandForReplacements(action.Shell, values)
 	parsedShellCommand = sv.ReplaceEntityVars(entityPrefix, parsedShellCommand)
+	redactedShellCommand := redactShellCommand(parsedShellCommand, action.Arguments, values)
 
 	if err != nil {
 		return "", err
@@ -74,12 +75,33 @@ func parseActionArguments(values map[string]string, action *config.Action, entit
 
 	log.WithFields(log.Fields{
 		"actionTitle": action.Title,
-		"cmd":         parsedShellCommand,
+		"cmd":         redactedShellCommand,
 	}).Infof("Action parse args - After")
 
 	return parsedShellCommand, nil
 }
 
+func redactShellCommand(shellCommand string, arguments []config.ActionArgument, argumentValues map[string]string) string {
+	for _, arg := range arguments {
+		if arg.Type == "password" {
+			argValue, exists := argumentValues[arg.Name]
+
+			if !exists {
+				log.Warnf("Redact shell command: Argument %s not found in values", arg.Name)
+				continue
+			}
+
+			if argValue == "" {
+				continue 
+			}
+
+			shellCommand = strings.ReplaceAll(shellCommand, argValue, "<redacted>")
+		}
+	}
+
+	return shellCommand
+}
+
 func typecheckActionArgument(name string, value string, action *config.Action) error {
 	arg := action.FindArg(name)
 

+ 34 - 0
service/internal/executor/arguments_test.go

@@ -132,3 +132,37 @@ func TestTypeSafetyCheckRegex(t *testing.T) {
 		})
 	}
 }
+
+func TestRedactShellCommand(t *testing.T) {
+	cmd := "echo 'The password for Fred is toomanysecrets'"
+
+	args := []config.ActionArgument{
+		{
+			Name: "personName",
+			Type: "ascii",
+		},
+		{
+			Name: "password",
+			Type: "password",
+		},
+	}
+
+	values := map[string]string{
+		"personName": "Fred",
+		"password": "toomanysecrets",
+	}
+
+	res := redactShellCommand(cmd, args, values)
+
+	assert.Equal(t, "echo 'The password for Fred is <redacted>'", res, "Redacted shell command should mask the password argument")
+
+	// Test with empty password
+	values["password"] = ""
+	res = redactShellCommand(cmd, args, values)
+	assert.Equal(t, cmd, res, "Empty password should not change the command")
+
+	// Test with missing password argument
+	delete(values, "password")
+	res = redactShellCommand(cmd, args, values)
+	assert.Equal(t, cmd, res, "Missing password argument should not change the command")
+}