3 ms·
tl;dr - If worried about leaking the path to a secret file, use <() (e.g. <( < "${secret_file_path}")) which makes an opaque ephemeral file i.e. /dev/fdX on the
by jspielberg 5y ago
tl;dr - If worried about leaking the path to a secret file, use <() (e.g. <( < "${secret_file_path}")) which makes an opaque ephemeral file i.e. /dev/fdX on the command line (1)
Sorry for the top level comment, but I am surprised this hasn't been shared by someone else already. Process substitution(1) (e.g. <(SECRET_STUFF_HERE)) totally solves the problem of leaking secrets to the process table.
From RTFA, the author is using "$(< $STEPPATH/certs/root_ca.crt)" and is concerned about leaking "$STEPPATH/certs/root_ca.crt" to the process table. If the Author instead ran <(< $STEPPATH/certs/root_ca.crt) the process table would just have some junk ephemeral file path instead.
For example... lets say for an arbitrary example, I didn't want folks knowing from the process table that I was getting the file details of /etc/passwd
### LEAKY
~ % wc /etc/passwd
110 297 6946 /etc/passwd
I could instead use process substitution:
% wc <( < /etc/passwd )
110 297 6946 /dev/fd/11
I have found this to be most useful not for files, but for temporary secret variables that I want to wrap in a file, but not have to deal with the cleanup and management of that file.
For a shell variable example, rather than writing "B64 is not encryption" to a file, and then having to cleanup that file... use process substitution to create the temporary file which doesn't leak to the process table.
## Don't do :
~ % echo "B64 is not encryption" | base64
QjY0IGlzIG5vdCBlbmNyeXB0aW9uCg==
## Do this instead; also 'echo' is a bash builtin and won't leak
~ % base64 <(echo "B64 is not encryption")
QjY0IGlzIG5vdCBlbmNyeXB0aW9uCg==
Or if used in scripting:
secret="B64 is not encryption"
bar="$(base64 <(echo "${secret}"))"
Some caveats: This only works for commands that accept files for arguments. If a command requires a secret to be passed in as a plaintext argument, then maybe the right answer is to rethink using that command in the first place (maybe <<<"HERESTRINGS" (2) helps in that case though I doubt it).
PROTIP: And for the love of all that's holy... run shellcheck(3) before considering running your script for realz if you want to keep your butt out of the fire. Also, the google shell style guide (4) is full of practical/good stuff. Shellcheck and the google style guide are pretty magical. I lost 10 lbs without dieting, became more attractive, and married my wife from following the guidance from those two resources. You can too! (caveat lector, ymmv, not legal advice (ianal), wife is already taken... sorry)
---
(1) https://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html https://www.gnu.org/software/bash/manual/html_node/Process-S...
(2) https://en.wikipedia.org/wiki/Here_document#Here_strings https://en.wikipedia.org/wiki/Here_document#Here_strings
(3) https://github.com/koalaman/shellcheck https://github.com/koalaman/shellcheck
(4) https://google.github.io/styleguide/shellguide.html https://google.github.io/styleguide/shellguide.html
- inshadows 5y agoHow is the first case ("Don't do :") in base64 example different from the second one? It seems to me to be exactly same thing. In both cases base64 reads from stdin and echo builtin is used. What am I missing?
- jspielberg 5y agoIn the second case it isn’t actually reading from standard in, but from an process listing opaque ephemeral file.