Skip to content
shellhacks.dev
Security

Avoid secrets on the command line

A secret passed as a command line argument is visible in ps to every local user. Pass it through standard input or a file descriptor instead.

1 min read
Summarize in AI

A program takes a token with --token=..., and while it runs, any user on the machine can read it.

Shell
python3 -c 'import time; time.sleep(30)' --token=s3cret &
pid=$!
ps -o args= -p $pid
tr '\0' ' ' < /proc/$pid/cmdline; echo
kill $pid
echo ---
printf '%s' 's3cret' | python3 -c 'import sys; print("read", len(sys.stdin.read()), "bytes from stdin")'
Text
python3 -c import time; time.sleep(30) --token=s3cret
python3 -c import time; time.sleep(30) --token=s3cret
---
read 6 bytes from stdin

The argument vector of every process is public. ps shows it to all users and /proc/PID/cmdline is readable by everyone unless /proc is mounted with hidepid, as the proc manual describes. The same secret never appears in the arguments when it is sent on standard input, as the last command does, and the receiving program reads it from there.

Environment variables are not a fix either: /proc/PID/environ is readable by the owner and root, and child processes inherit them. Shell history records the typed command too, so the first line is a leak even before the process runs. Use a file with mode 600 or a descriptor when the program offers no stdin option.

Share

More snippets

Security

Avoid predictable temp names

Never build a temp file name from $$ or a fixed string. An attacker who guesses it can plant a symlink, and mktemp picks an unused random name with mode 600.

1 min read
Security

Avoid eval on input

Never pass input to eval. Run a command held in an array as "${cmd[@]}", or escape a value with printf %q when eval cannot be avoided.

1 min read
Security

Validate input with a whitelist

Validate input against a list of allowed values with a case statement. A grep check with ^ and $ can be fooled by a value that holds a newline.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.