Skip to content
shellhacks.dev
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
Summarize in AI

A script writes to /tmp/app.$$, and a local user who can guess the process ID can make it overwrite another file.

Shell
echo precious > victim.txt
ln -s "$PWD/victim.txt" /tmp/app.12345
echo "scratch data" > /tmp/app.12345
cat victim.txt
rm -f /tmp/app.12345
echo ---
tmp=$(mktemp)
echo "scratch data" > "$tmp"
stat -c '%A %U' "$tmp"
rm -f "$tmp"
Text
scratch data
---
-rw------- root

The first redirect follows the symbolic link that was planted in the shared directory, so the scratch data replaces the contents of victim.txt. Process IDs are small and guessable, and the same attack works for any fixed name. mktemp creates the file itself with O_EXCL, so it fails if the name exists, and it chooses a random suffix and mode 600, as the mktemp manual states. Many systems also set fs.protected_symlinks to block this in sticky directories.

Do not use mktemp -u, which only prints a name and brings the race back. Clean up with trap 'rm -f "$tmp"' EXIT. For several files, mktemp -d makes a private directory to put them in. The protection against symlinks is a system setting, and containers and older kernels may not have it on.

Share

More snippets

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
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
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

Get new posts by email

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

Unsubscribe in one click. No spam, ever.