Skip to content
shellhacks.dev
Security

Quote variables passed to commands

Quote variables you pass to commands. An unquoted expansion splits on spaces and expands globs, and a value that starts with a dash becomes an option.

1 min read
Summarize in AI

A script deletes files it was never asked to touch, because a value with a space or a dash in it was passed on unquoted.

Shell
touch 'my file.txt' my file.txt
input='my file.txt'
rm $input
ls
echo ---
input='-la'
ls $input | head -n 2
echo ---
ls -- "$input"
Text
my file.txt
---
total 8
drwxr-xr-x 2 root root 4096 Nov  6 18:04 .
---
ls: cannot access '-la': No such file or directory

An unquoted expansion is split into words on whitespace and each word is then treated as a glob pattern, so rm $input removed the two decoy files my and file.txt and left the file the user meant. A value beginning with a dash is read as an option, which is how ls $input listed the directory. Quoting keeps the value as one word, and -- ends option parsing so it cannot be taken as one, as the Bash manual describes under word splitting. The last command fails because no file has that name, which is the right result.

Quoting stops the shell from splitting and globbing, but a program that interprets its argument, like grep, sed -e or ssh host, can still be attacked through its own syntax. -- is accepted by most GNU and POSIX tools, not by all. Run shellcheck on scripts, which reports the missing quotes as SC2086.

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.