hackerschoice / gsocket

Connect like there is no firewall. Securely.
https://www.gsocket.io
BSD 2-Clause "Simplified" License
1.45k stars 122 forks source link

Add support obtaining the secret via a command #103

Open Flowdalic opened 4 months ago

Flowdalic commented 4 months ago

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
rodolfovillordo commented 4 months ago

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

[1] https://www.man7.org/linux/man-pages//man1/bash.1.html

Flowdalic commented 4 months ago

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.

Flowdalic commented 3 months ago

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.