Subject: | Unable to securely download to a tempfile |
Background
==========
The ":content_file => $filename" header tells LWP::UserAgent to place the contents of a retrieved file into the specified filename.
However, some applications want to download to a temporary file. This can't be done securely with the current API. At least, not without writing handlers/callbacks.
File::Temp is the (most common) supported way to produce a safe temporary file. It returns a file handle. (It also handles deleting the temporary file when it goes out of scope or is closed.)
One can obtain the corresponding filename and pass it to :content_file - but this introduces a race condition. An attacker might symlink the filename to an important file, which LWP would open for write... Also, the open() in LWP will supersede the temporary file, so the File::Temp handle is useless for reading the data. Thus, the caller must re-open() the file by name - which is another race condition. Finally, on some OSes, superseding an open file will fail.
Suggestion
==========
A straightforward solution would be to add a "content_fh => <filehandle>" option. This would bypass the open() in LWP and simply write data to the specified file handle.
In this case, LWP should not close() the file handle, or attempt to position it. (In some other applications, the fh could be non-seekable (e.g. a pipe).)
The caller would be responsible for seek()ing to the start of data if desired (in the temp file case) and for closing the file handle.
This solution would also support passing an anonymous temporary file handle (open() of undef), which on some operating systems doesn't have a filename.
Also, the documentation could be clearer that :content_file stores decoded_content...
Thanks!