Merge pull request 'sops: don't leak secret key in debug logs' (#5411) from no-leaks into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5411
This commit is contained in:
Mic92
2025-10-07 10:00:47 +00:00
2 changed files with 10 additions and 2 deletions

View File

@@ -355,7 +355,10 @@ def get_public_age_key_from_private_key(privkey: str) -> str:
cmd = nix_shell(["age"], ["age-keygen", "-y"]) cmd = nix_shell(["age"], ["age-keygen", "-y"])
error_msg = "Failed to get public key for age private key. Is the key malformed?" 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() return res.stdout.rstrip(os.linesep).rstrip()

View File

@@ -294,6 +294,8 @@ class RunOpts:
# This is needed for GUI applications # This is needed for GUI applications
graphical_perm: bool = False graphical_perm: bool = False
trace: bool = True 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]: 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 cmdlog.isEnabledFor(logging.DEBUG) and options.trace:
if options.input and isinstance(options.input, bytes): 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 = "<<REDACTED>>"
elif any(
not ch.isprintable() for ch in options.input.decode("ascii", "replace") not ch.isprintable() for ch in options.input.decode("ascii", "replace")
): ):
filtered_input = "<<binary_blob>>" filtered_input = "<<binary_blob>>"