|Subject:||File::Temp and unsafe shell characters|
The File::Temp documentation doesn't mention anything about the characters used in the generated temporary file, and whether they might be unsafe to use in shell commands or single-argument open(). This matters because it's often a tempting thing to say # Create a temporary file with some content. my ($fh, $filename) = File::Temp::tempfile; print $fh 'some text' or die $!; close $fh or die $!; # Now for whatever reason we re-open the file. open FH, $filename or die $!; # Alternatively, we might do something like this: system("gzip $filename") && die; However, the above code is buggy; File::Temp doesn't make any guarantee that the filename returned will be shell-safe. For example % mkdir '>' % mkdir '>/etc'; % TMPDIR='>/etc' perl -MFile::Temp -e '($fh, $filename) = File::Temp::tempfile; print $filename' In this scenario, if an attacker can create a directory containing shell characters and then set TMPDIR, he can cause the above program to write a file in /etc or another directory of his choice. Or he could put backticks into the directory name to run an arbitrary command when it is used in system(), etc. This is not strictly a bug in File::Temp because the documentation does not make any promise that the filename returned will be safe. But in the absence of an explicit warning programmers might assume so; I know I did. So I would like to request one of three things: - Update the File::Temp documentation to note that the filename returned is not guaranteed shell-safe and you should check it first before using it in one-argument system(), open() etc. - Consider adding a safe mode where the filename returned is guaranteed not to contain any nasty characters. Presumably if the tempdir returned by File::Spec contains these characters then File::Temp should die rather than return an unsafe filename to the user, if safe mode is on. - Consider making safe mode the default. A quick search for vulnerable code found this example from Bioperl: ($tfh,$tfile) = $obj->tempfile(); print $tfh ("test1"); close($tfh); open(IN, $tfile) or die("cannot open $tfile"); I am sure there are many other instances of the same bug, which will sometimes be exploitable.