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.
A script writes to /tmp/app.$$, and a local user who can guess the process ID can make it overwrite another file.
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"scratch data
---
-rw------- rootThe 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.