To delete the temporary file as soon as possible, you can write a wrapper, like:
#!/bin/sh
the-application "$1"
rm -f "$1"
replacing the-application
by the name of the real executable, and ask Firefox to use this wrapper instead of the application. Or:
#!/bin/sh
the-application "$1"
case "$1" in
/tmp/*) rm -f "$1" ;;
esac
This form is safer in case future Firefox versions do not create a new file for "file:" URL's (you don't want the file to be removed in this case).
Note that some applications return immediately and may fail to work correctly if the file is removed before the application is quit. In such a case, there isn't much you can do (at least in a reliable way).
Concerning the alternative (to replace an existing file with the same name), this can yield clashes with other applications that use /tmp
, with possible security implications. This is not a good idea in general.
Use the mktemp
utility to create a temporary file with an unpredictable name. It isn't standardized by POSIX, but it's available on *BSD as well as Linux.
> /tmp/predictable.$RANDOM
is not a good choice because it's mostly predictable¹, which opens your script to an attack where the attacker can trick your script into overwriting a file you have write access to, or giving them access to the temporary file. This is an insecure temporary file vulnerability. mktemp
doesn't have this vulnerability because creates the file safely (it won't overwrite an existing file, even if symbolic links are involved) and uses a sufficiently unpredictable name to avoid a denial of service.
If creating one temporary file and working with it is not good enough, create a temporary directory with mktemp -d
, and work in there.
mktemp
also takes care to use $TMPDIR
if the variable is set, falling back to /tmp
if it's unset.
More and more distributions set up TMPDIR
to be a private directory, e.g. /run/1234/tmp
where 1234
is your UID. This eliminates the risk of temporary file vulnerabilities, at the cost of no longer being able to share temporary files between users (which is occasionally useful, but not very often; /tmp
is still available, just not TMPDIR
).
If you need a reproducible file name, then create a file with a well-defined name (with no random component) under the user's home directory. The modern convention is the XDG user directory specification. If the file could be removed without causing data loss, use the XDG_CACHE_HOME
environment variable, defaulting to ~/.cache
. You should probably create a subdirectory named after your application and work in there.
CACHE_DIR="${XDG_CACHE_HOME:-"$HOME/.cache"}"/Wildcard-scripts
[ -d "$CACHE_DIR" ] || mkdir -p -- "$CACHE_DIR"
CACHE_FILE="$CACHE_DIR/tmpfileformyscript"
¹ Not only does $RANDOM
only takes 32767 possible values, but it's easy to predict without even trying many values. Bash's random number generator is a LCG seeded by the PID and time of first use. Zsh's is the platform's rand
seeded by startup time. ATT Ksh's is the platform's rand
seeded by PID. Mksh's is an LCG with a more complex, but still not security-quality seed. All of them can be predicted by another process with a fairly large chance of success.
Best Answer
The FHS mandates that
/tmp
exist, as does POSIX so you can rely on its being there (at least on compliant systems; but really it’s pretty much guaranteed to be present on Unix-like systems). But you shouldn’t: the system administrator or the user may prefer other locations for temporary files. See Finding the correct tmp dir on multiple platforms for more details.