Add support obtaining the secret via a command
Opened this issue · 3 comments
The gs-netcat
tool currently supports obtaining the secret via a command line argument (-s
) or retrieving it from a file (-k
).
My secrets are stored in pass in pass
. For example pass gsocket/foo
outputs the gsocket secret of the machine foo
on stdout. It would be great if I could invoke gs-netcat
so that it directly obtains the password from the stdout of a specified command. For example, using a new command line option -K
:
$ gs-netcat -K "pass gsocket/foo" -i
Have you tried command substitution?
From bash manual[1]
Command Substitution
Command substitution allows the output of a command to replace the command name. There are two forms:
$(command)
or
`command`
Bash performs the expansion by executing command in a subshell environment and replacing the command substi‐
tution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are
not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be re‐
placed by the equivalent but faster $(< file).
When the old-style backquote form of substitution is used, backslash retains its literal meaning except when
followed by $, `, or \. The first backquote not preceded by a backslash terminates the command substitution.
When using the $(command) form, all characters between the parentheses make up the command; none are treated
specially.
Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes
with backslashes.
If the substitution appears within double quotes, word splitting and pathname expansion are not performed on
the results
In your case it would be something like:
$ gs-netcat -S $(pass gsocket/foo) -i
Sure, that would work. However, built-in support would completely avoid the secret from appearing on the command line. And that is the goal here.
While gsocket seems to redact the secret, so that it doesn't appear, for example, in ps
output, it is preferable to don't pass secrets via the command arguments in the first place. Simply because it reduces the possibility to leak secrets.
FTR and to illustrate the problem, I use the following bash script, placed under ~/bin/gs-shell, to establish a gsocket remote shell connection with the credential extracted from pass.
#!/usr/bin/env bash
set -eu
TMPFILE=$(mktemp --tmpdir="${TMPDIR:-/tmp}")
trap 'rm -f ${TMPFILE}' EXIT
pass show gsocket/root-shell/"${1}" > "${TMPFILE}"
# No exec here because we want the trap to clean up after us.
gs-netcat -q -k "${TMPFILE}" -i
As you can see, the problem is that the secret lies in the temporary directory even after it was obtained from gs-netcat. Generally speaking, the temporary directory and the secret within is accessible by every application of my user (and, of course, the root user and its application).
If I where able to pipe the password via stdin into gs-netcat, then the password would not be exposed longer than required, significantly reducing (or even closing) the window where it could be picked up by an unauthorized entity.