From 10ed2cc7f7762c4c32e44bb13268e15267c297f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Tue, 7 Oct 2025 11:30:54 +0200 Subject: [PATCH] sops: don't leak secret key in debug logs --- pkgs/clan-cli/clan_cli/secrets/sops.py | 5 ++++- pkgs/clan-cli/clan_lib/cmd/__init__.py | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/secrets/sops.py b/pkgs/clan-cli/clan_cli/secrets/sops.py index bdab5a318..c69d14425 100644 --- a/pkgs/clan-cli/clan_cli/secrets/sops.py +++ b/pkgs/clan-cli/clan_cli/secrets/sops.py @@ -355,7 +355,10 @@ def get_public_age_key_from_private_key(privkey: str) -> str: cmd = nix_shell(["age"], ["age-keygen", "-y"]) error_msg = "Failed to get public key for age private key. Is the key malformed?" - res = run(cmd, RunOpts(input=privkey.encode(), error_msg=error_msg)) + res = run( + cmd, + RunOpts(input=privkey.encode(), error_msg=error_msg, sensitive_input=True), + ) return res.stdout.rstrip(os.linesep).rstrip() diff --git a/pkgs/clan-cli/clan_lib/cmd/__init__.py b/pkgs/clan-cli/clan_lib/cmd/__init__.py index b730a34b4..832a88eaa 100644 --- a/pkgs/clan-cli/clan_lib/cmd/__init__.py +++ b/pkgs/clan-cli/clan_lib/cmd/__init__.py @@ -294,6 +294,8 @@ class RunOpts: # This is needed for GUI applications graphical_perm: bool = False trace: bool = True + # Mark input as sensitive to prevent it from being logged (e.g., private keys, passwords) + sensitive_input: bool = False def cmd_with_root(cmd: list[str], graphical: bool = False) -> list[str]: @@ -349,7 +351,10 @@ def run( if cmdlog.isEnabledFor(logging.DEBUG) and options.trace: if options.input and isinstance(options.input, bytes): - if any( + # Always redact sensitive input (e.g., private keys, passwords) + if options.sensitive_input: + filtered_input = "<>" + elif any( not ch.isprintable() for ch in options.input.decode("ascii", "replace") ): filtered_input = "<>"