Skip to content

Secret substitution passes secret values through argv and is not byte-preserving #723

Description

@dniku

Summary

shb.replaceSecrets currently routes secret contents through shell command substitution and then through command-line arguments. This is fragile for correctness and security.

#720 improves multiline secret handling by replacing sed with a Python replacement helper, fixing the immediate multiline substitution failure. However, the broader design still passes secret values as CLI arguments, which means secret contents are not handled as opaque file data.

Problem

Secret values are effectively read with shell command substitution, e.g. conceptually:

"$(cat "$secret_path")"

and then passed as arguments to the replacement command.

This has several consequences:

  • Trailing newlines are stripped by shell command substitution.
  • NUL bytes cannot be represented in shell strings / argv.
  • Secret values can be exposed through the process list while replacement is running.
  • The implementation remains difficult to reason about because transform operates in this shell-expression layer.

Why this matters

Some SHB “secrets” are not just short passwords. They can be whole config-like files, for example rclone.conf, private keys, certificates, htpasswd files, or other externally generated credential files.

For these cases, SHB should either preserve the secret file contents exactly or clearly document/reject unsupported inputs. Silently changing contents, such as dropping the final newline, is surprising.

Expected behavior

Secret substitution should preserve secret contents exactly, at least for normal text secrets including trailing newlines.

If binary/NUL-containing secrets are not supported, SHB should fail clearly rather than silently corrupting the value.

Secret values should not be passed through argv.

Suggested direction

Pass secret file paths to the replacement helper and let the helper read the files directly, instead of expanding secret contents in shell and passing them as command-line arguments.

This would also make it possible to use or mirror the design of nixpkgs’ replace-secret helper, as mentioned in PR #720.

Longer term, it may be worth reconsidering transform. It makes the secret pipeline substantially harder to make safe because transforms currently operate on shell expressions rather than on explicit file inputs/outputs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions